com.technophobia.substeps.step.ProjectStepImplementationLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.technophobia.substeps.step.ProjectStepImplementationLoader.java

Source

/*******************************************************************************
 * Copyright Technophobia Ltd 2012
 * 
 * This file is part of the Substeps Eclipse Plugin.
 * 
 * The Substeps Eclipse Plugin is free software: you can redistribute it and/or modify
 * it under the terms of the Eclipse Public License v1.0.
 * 
 * The Substeps Eclipse Plugin is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Eclipse Public License for more details.
 * 
 * You should have received a copy of the Eclipse Public License
 * along with the Substeps Eclipse Plugin.  If not, see <http://www.eclipse.org/legal/epl-v10.html>.
 ******************************************************************************/
package com.technophobia.substeps.step;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.jar.JarFile;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import com.technophobia.substeps.FeatureEditorPlugin;
import com.technophobia.substeps.glossary.StepImplementationsDescriptor;
import com.technophobia.substeps.glossary.XMLSubstepsGlossarySerializer;
import com.technophobia.substeps.supplier.Transformer;

public class ProjectStepImplementationLoader implements Transformer<IProject, List<StepImplementationsDescriptor>> {

    private final XMLSubstepsGlossarySerializer serializer;

    public ProjectStepImplementationLoader() {
        this.serializer = new XMLSubstepsGlossarySerializer();
    }

    @Override
    public List<StepImplementationsDescriptor> from(final IProject project) {
        final List<StepImplementationsDescriptor> stepImplementationsDescriptors = new ArrayList<StepImplementationsDescriptor>();
        if (isJavaProject(project)) {
            final IJavaProject javaProject = toJavaProject(project);

            final String[] dependencies = findDependenciesFor(javaProject);

            for (final String dependency : dependencies) {
                stepImplementationsDescriptors.addAll(findStepImplementationDescriptorsForDependency(dependency));
            }
        }
        return stepImplementationsDescriptors;
    }

    private boolean isJavaProject(final IProject project) {
        try {
            return project.hasNature(JavaCore.NATURE_ID);
        } catch (final CoreException e) {
            FeatureEditorPlugin.instance()
                    .warn("Could not determine if project " + project.getName() + " is a java project");
            return false;
        }
    }

    private IJavaProject toJavaProject(final IProject project) {
        return JavaCore.create(project);
    }

    private String[] findDependenciesFor(final IJavaProject javaProject) {
        try {
            final IPackageFragmentRoot[] fragmentRoots = javaProject.getPackageFragmentRoots();
            final Collection<String> rootPaths = new ArrayList<String>(fragmentRoots.length);
            for (int i = 0; i < fragmentRoots.length; i++) {
                if (fragmentRoots[i].getKind() == IPackageFragmentRoot.K_BINARY) {
                    final String path = getPathFor(fragmentRoots[i]);
                    if (path != null) {
                        rootPaths.add(path);
                    }
                }
            }
            return rootPaths.toArray(new String[rootPaths.size()]);
        } catch (final JavaModelException ex) {
            FeatureEditorPlugin.instance()
                    .warn("Could not get package fragment roots for project " + javaProject.getProject().getName());
            return new String[0];
        }
    }

    /**
     * Returns the path for this fragment in a OS friendly string. Note that in
     * windows, the method for getting the absolute path varies for source
     * folders and jars
     * 
     * @param fragmentRoot
     *            The fragment containing classes
     * @return The path of this fragment root, os-friendly
     */
    private String getPathFor(final IPackageFragmentRoot fragmentRoot) {
        final IResource resource = fragmentRoot.getResource();
        final IPath path;
        if (resource != null) {
            path = resource.getRawLocation();
        } else {
            path = fragmentRoot.getPath().makeAbsolute();
        }
        return path.toOSString();
    }

    private List<StepImplementationsDescriptor> findStepImplementationDescriptorsForDependency(final String path) {
        JarFile jarFile = null;
        try {
            jarFile = new JarFile(new File(path));
            final List<StepImplementationsDescriptor> stepImplementationDescriptors = serializer
                    .loadStepImplementationsDescriptorFromJar(jarFile);
            return stepImplementationDescriptors != null ? stepImplementationDescriptors
                    : Collections.<StepImplementationsDescriptor>emptyList();
        } catch (final IOException ex) {
            FeatureEditorPlugin.instance().warn("Could not open jar file " + path);
        } finally {
            try {
                if (jarFile != null) {
                    jarFile.close();
                }
            } catch (final IOException e) {
                FeatureEditorPlugin.instance().warn("Could not close jar file " + path);
            }
        }

        return Collections.<StepImplementationsDescriptor>emptyList();
    }
}