org.cloudsmith.geppetto.pp.dsl.ui.container.PPWorkspaceProjectsStateHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudsmith.geppetto.pp.dsl.ui.container.PPWorkspaceProjectsStateHelper.java

Source

/**
 * Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below.
 * 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:
 *   Cloudsmith
 * 
 */
package org.cloudsmith.geppetto.pp.dsl.ui.container;

import java.io.File;
import java.util.Collections;
import java.util.List;

import org.apache.log4j.Logger;
import org.cloudsmith.geppetto.diagnostic.Diagnostic;
import org.cloudsmith.geppetto.forge.Forge;
import org.cloudsmith.geppetto.forge.v2.model.Dependency;
import org.cloudsmith.geppetto.forge.v2.model.Metadata;
import org.cloudsmith.geppetto.forge.v2.model.ModuleName;
import org.cloudsmith.geppetto.semver.Version;
import org.cloudsmith.geppetto.semver.VersionRange;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.xtext.ui.XtextProjectHelper;
import org.eclipse.xtext.ui.containers.AbstractStorage2UriMapperClient;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Lists;
import com.google.inject.Inject;

/**
 * Helper for Puppet Projects.
 * 
 */
public class PPWorkspaceProjectsStateHelper extends AbstractStorage2UriMapperClient {

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

    @Inject
    private IWorkspace workspace;

    @Inject
    private Forge forge;

    /**
     * Returns the best matching project (or null if there is no match) among the projects in the
     * workspace.
     * A translation is made from "/" to "-" in the separators in dependencies. (Should be checked elsewhere).
     * 
     * @param d
     * @return
     */
    protected IProject getBestMatchingProject(Dependency d) {
        ModuleName name = d.getName();
        if (name == null)
            return null;
        // Names with "/" are not allowed
        name = name.withSeparator('-');
        String namepart = name + "-";
        BiMap<IProject, Version> candidates = HashBiMap.create();
        int len = namepart.length();

        for (IProject p : getWorkspaceRoot().getProjects()) {
            String n = p.getName();
            if (n.startsWith(namepart) && n.length() > len && isAccessibleXtextProject(p)) {
                try {
                    candidates.put(p, Version.create(p.getName().substring(len)));
                } catch (IllegalArgumentException e) {
                    // Project name does not end with a valid version. Just skip it
                }
            }
        }
        if (candidates.isEmpty())
            return null;

        VersionRange vr = d.getVersionRequirement();
        if (vr == null)
            vr = VersionRange.ALL_INCLUSIVE;
        Version best = vr.findBestMatch(candidates.values());
        return candidates.inverse().get(best);
    }

    public List<String> getVisibleProjectNames(IProject project) {
        if (isAccessibleXtextProject(project)) {
            File moduleDir = project.getLocation().toFile();
            List<String> result = Lists.newArrayList();

            // parse the "Modulefile/metadata.json" and get full name and version, use this as name of target entry
            // TODO: Improve this to report diagnostics
            try {
                Diagnostic diag = new Diagnostic();
                Metadata metadata = forge.createFromModuleDirectory(moduleDir, false, null, null, diag);
                if (metadata != null) {
                    for (Dependency d : metadata.getDependencies()) {
                        IProject best = getBestMatchingProject(d);
                        if (best != null)
                            result.add(best.getName());
                        else {
                            // TODO: need to inform the user about this somehow, but can't create markers here
                        }
                    }
                }
            } catch (Exception e) {
                if (log.isDebugEnabled())
                    log.debug("Could not parse any metadata from project: '" + project.getName() + "'", e);
            }
            return result;
        }
        return Collections.emptyList();
    }

    protected IWorkspaceRoot getWorkspaceRoot() {
        return workspace.getRoot();
    }

    /**
     * Initializes visible handles from PP 'Modulefile/metadata.json' manifests. In case of errors, a partially
     * parsed result is returned and error is logged.
     * 
     * @param handle
     * @return
     */
    public List<String> initVisibleHandles(String handle) {
        IProject project = getWorkspaceRoot().getProject(handle);
        return getVisibleProjectNames(project);
    }

    protected boolean isAccessibleXtextProject(IProject p) {
        return p != null && XtextProjectHelper.hasNature(p);
    }

    public void setWorkspace(IWorkspace workspace) {
        this.workspace = workspace;
    }
}