org.eclipselabs.jar2uml.test.J2UTestCase.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipselabs.jar2uml.test.J2UTestCase.java

Source

/*******************************************************************************
 * Copyright (c) 2007-2010 Dennis Wagelaar, Vrije Universiteit Brussel.
 * 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:
 *     Dennis Wagelaar, Vrije Universiteit Brussel
 *******************************************************************************/
package org.eclipselabs.jar2uml.test;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;

import org.junit.Assert;

import org.apache.bcel.classfile.ClassFormatException;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
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.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipselabs.jar2uml.JarToUML;
import org.eclipselabs.jar2uml.JarToUMLResources;
import org.osgi.framework.Bundle;

/**
 * Shared functionality for Jar2UML test cases.
 * @author Dennis Wagelaar <dennis.wagelaar@vub.ac.be>
 */
public abstract class J2UTestCase extends EMFTestCase {

    public static final String PLUGIN_ID = "org.eclipselabs.jar2uml.test";
    public static final String PLUGIN_URI = "platform:/plugin/" + PLUGIN_ID;

    public static final Bundle bundle = Platform.getBundle(PLUGIN_ID);
    public static final Bundle dataBundle = Platform.getBundle(PLUGIN_ID + ".data");

    public static final String pkServletDepsUri = PLUGIN_URI + "/resources/platformkitservlet.deps.uml";
    public static final String pkServletWar = "resources/platformkitservlet.war";

    public static final String atJar = "resources/at2-build080507/ambienttalk2.jar";
    public static final String antlrJar = "resources/at2-build080507/lib/antlr.jar";
    public static final String getoptJar = "resources/at2-build080507/lib/java-getopt-1.0.13.jar";
    public static final String atModelUri = PLUGIN_URI + "/resources/at2-build080507/ambienttalk2.uml";
    public static final String atDepsModelUri = PLUGIN_URI + "/resources/at2-build080507/ambienttalk2.deps.uml";

    public static final String instantmessengerJar = "resources/instantmessenger.jar";

    public static final String jaxbOsgiJar = "resources/jaxb-osgi.jar";
    public static final String jaxbOsgiDepsUri = PLUGIN_URI + "/resources/jaxb-osgi.deps.uml";

    public static final String j2eeJar = "resources/j2ee.jar";
    public static final String j2eeDepsUri = PLUGIN_URI + "/resources/j2ee.deps.uml";

    /**
     * Copies the file at the given path to the root of the given project.
     * @param path
     * @param project
     * @return The target file.
     * @throws CoreException
     * @throws IOException
     */
    public static IFile copyFileToProject(String path, IProject project) throws CoreException, IOException {
        String targetPath = fileName(path);
        IFile file = project.getFile(targetPath);
        if (!file.exists()) {
            JarToUMLResources.logger.info("Creating jar file: " + file);
            URL url = bundle.getResource(path);
            file.create(url.openStream(), true, null);
        }
        return file;
    }

    /**
     * Copies the class file to the right place in the given project.
     * @param clazz
     * @param project Must be a Java project!
     * @return The target file.
     * @throws CoreException
     * @throws IOException
     */
    public static IFile copyClassToJavaProject(final Class<?> clazz, final IProject project)
            throws CoreException, IOException {
        String path = classFilePath(clazz);
        JarToUMLResources.logger.info("copying class file: " + path);
        IJavaProject jproject = JarToUML.getJavaProject(project.getFullPath());
        IPath outPath = jproject.getOutputLocation();
        JarToUMLResources.logger.info("class file path: " + outPath);
        IPath classFilePath = outPath.append(path);
        final IFile classFile = ResourcesPlugin.getWorkspace().getRoot().getFile(classFilePath);
        ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
            public void run(IProgressMonitor monitor) throws CoreException {
                if (!classFile.exists()) {
                    createPath((IFolder) classFile.getParent());
                    try {
                        classFile.create(getClassContents(clazz), true, null);
                        JarToUMLResources.logger.info("created file: " + classFile);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }, null);
        return classFile;
    }

    /**
     * @param clazz
     * @return the contents of clazz as an {@link InputStream}
     * @throws IOException
     */
    public static InputStream getClassContents(Class<?> clazz) throws IOException {
        String path = classFilePath(clazz);
        URL classURL = bundle.getResource(path);
        if (classURL == null) {
            dataBundle.getResource(path);
        }
        Assert.assertNotNull(classURL);
        return classURL.openStream();
    }

    /**
     * @param clazz
     * @return The file path of clazz relative to the classpath root.
     * Works only for named classes.
     */
    public static String classFilePath(Class<?> clazz) {
        return clazz.getName().replace('.', '/').concat(".class");
    }

    /**
     * @param path
     * @return The last segment of path (after last '/').
     */
    public static String fileName(String path) {
        return path.substring(path.lastIndexOf('/') + 1);
    }

    /**
     * @param file
     * @return The {@link JarFile} corresponding to file.
     * @throws IOException
     */
    public static JarFile jarFile(IFile file) throws IOException {
        return new JarFile(file.getLocation().toFile());
    }

    /**
     * @param file
     * @return The {@link JarInputStream} corresponding to file.
     * @throws IOException
     * @throws CoreException 
     */
    public static JarInputStream jarInputStream(IFile file) throws IOException, CoreException {
        return new JarInputStream(file.getContents());
    }

    /**
     * @param name
     * @return A new project with the Java project nature.
     * @throws CoreException
     */
    public static IProject createJavaProject(final String name) throws CoreException {
        final IProject project = getProject(name);
        ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
            public void run(IProgressMonitor monitor) throws CoreException {
                if (!project.exists()) {
                    project.create(null);
                    project.open(null);
                    IProjectDescription description = project.getDescription();
                    String natures[] = new String[] { "org.eclipse.jdt.core.javanature" };
                    description.setNatureIds(natures);
                    project.setDescription(description, null);
                }
            }
        }, null);
        return project;
    }

    /**
     * @param name
     * @return The {@link IProject} with the given name, if any, <code>null</code> otherwise.
     */
    public static IProject getProject(String name) {
        return ResourcesPlugin.getWorkspace().getRoot().getProject(name);
    }

    /**
     * Creates path and its parents.
     * @param path
     * @throws CoreException
     */
    public static void createPath(IFolder path) throws CoreException {
        final IContainer parent = path.getParent();
        if (!parent.exists() && parent instanceof IFolder) {
            createPath((IFolder) parent);
        }
        if (!path.exists()) {
            path.create(true, true, null);
        }
    }

    /**
     * Loads a UML Model from the given EMF uri.
     * @param uri
     * @return The (first) root Model in the loaded resource, if any, <code>null</code> otherwise.
     */
    public static Model loadModelFromUri(String uri) {
        JarToUMLResources.logger.info("Loading UML model from: " + uri);
        Resource res = JarToUML.createResourceSet().getResource(URI.createURI(uri), true);
        return findModel(res);
    }

    /**
     * @param res
     * @return The (first) root Model in res, if any, <code>null</code> otherwise.
     */
    public static Model findModel(Resource res) {
        Model root = null;
        for (EObject e : res.getContents()) {
            if (e instanceof Model) {
                root = (Model) e;
                break;
            }
        }
        return root;
    }

    /**
     * @param element
     * @return A human-readable {@link String} that identifies element.
     */
    public static final String toString(Element element) {
        if (element instanceof NamedElement) {
            final String qName = ((NamedElement) element).getQualifiedName();
            if (qName != null) {
                return qName;
            } else {
                return element.toString();
            }
        } else {
            return element.toString();
        }
    }

    /**
     * Validates the model.
     * @param model
     */
    public static void validateModel(Model model) {
        assertNotNull(model);
        BasicDiagnostic diagnostics = new BasicDiagnostic();
        Map<Object, Object> context = new HashMap<Object, Object>();
        model.validateElementsPublicOrPrivate(diagnostics, context);
        model.validateHasNoQualifiedName(diagnostics, context);
        model.validateHasOwner(diagnostics, context);
        model.validateHasQualifiedName(diagnostics, context);
        model.validateMembersDistinguishable(diagnostics, context);
        model.validateNotOwnSelf(diagnostics, context);
        model.validateVisibilityNeedsOwnership(diagnostics, context);
        JarToUMLResources.logger.info("Model diagnostics: " + diagnostics.getMessage());
        assertEquals(Diagnostic.OK, diagnostics.getSeverity());
    }

    /**
     * Validates the use of "inferred" tags in element.
     * @param element
     * @return <code>true</code> iff element is marked as inferred
     */
    public static boolean validateInferredTags(Element element) {
        if ("true".equals(JarToUML.getAnnotationValue(element, "inferred"))) {
            // if this element is inferred, it cannot have any children marked as inferred
            boolean someChildrenInferred = false;
            for (Element child : element.getOwnedElements()) {
                someChildrenInferred |= validateInferredTags(child);
            }
            Assert.assertFalse(String.format(
                    "Some children of %s marked as inferred, while self is already marked as inferred",
                    toString(element)), someChildrenInferred);
            return true;
        } else {
            // if this element is not inferred, it cannot have all children marked as inferred
            boolean allChildrenInferred = true;
            boolean hasChildren = false;
            for (Element child : element.getOwnedElements()) {
                hasChildren = true;
                allChildrenInferred &= validateInferredTags(child);
            }
            allChildrenInferred = allChildrenInferred && hasChildren;
            Assert.assertFalse(String.format("All children of %s marked as inferred, while self not inferred",
                    toString(element)), allChildrenInferred);
            return false;
        }
    }

    /**
     * Creates a new {@link J2UTestCase}.
     */
    public J2UTestCase() {
        super();
    }

    /**
     * Creates a new {@link J2UTestCase}.
     * @param name
     */
    public J2UTestCase(String name) {
        super(name);
    }

    /*
     * (non-Javadoc)
     * @see junit.framework.TestCase#setUp()
     */
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        //
        // Refresh workspace
        //
        ResourcesPlugin.getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, null);
        JarToUMLResources.logger.info("setup done");
    }

    /*
     * (non-Javadoc)
     * @see junit.framework.TestCase#tearDown()
     */
    @Override
    protected void tearDown() throws Exception {
        JarToUMLResources.logger.info("starting teardown");
        super.tearDown();
    }

    /**
     * @param clazz
     * @return the parsed test class
     * @throws ClassFormatException
     * @throws IOException
     */
    protected JavaClass getTestClass(Class<?> clazz) throws ClassFormatException, IOException {
        final ClassParser parser = new ClassParser(getClassContents(clazz), classFilePath(clazz));
        return parser.parse();
    }

}