com.ebmwebsourcing.petals.services.jsr181.handlers.Jsr181GenerationHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.ebmwebsourcing.petals.services.jsr181.handlers.Jsr181GenerationHandler.java

Source

/******************************************************************************
 * Copyright (c) 2010-2013, Linagora
 *
 * 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:
 *       Linagora - initial API and implementation
 *******************************************************************************/

package com.ebmwebsourcing.petals.services.jsr181.handlers;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
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.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.progress.IProgressService;

import com.ebmwebsourcing.petals.common.generation.JbiXmlGenerationHelper;
import com.ebmwebsourcing.petals.common.generation.cdk5.components.Jsr181Provides1x;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.JaxWsUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.JaxWsUtils.JaxWsException;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.PetalsConstants;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.ResourceUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.WsdlUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.WsdlUtils.JbiBasicBean;
import com.ebmwebsourcing.petals.services.jsr181.PetalsJsr181Plugin;
import com.ebmwebsourcing.petals.services.utils.PetalsServicesProjectUtils;

/**
 * @author Vincent Zurczak - EBM WebSourcing
 */
public class Jsr181GenerationHandler extends AbstractHandler {

    /*
     * (non-Javadoc)
     * @see org.eclipse.core.commands.AbstractHandler
     * #execute(org.eclipse.core.commands.ExecutionEvent)
     */
    @Override
    public Object execute(final ExecutionEvent event) throws ExecutionException {

        final IJavaProject javaProject = getSelectedJavaProject();
        if (javaProject != null) {

            // Need for a confirmation?
            String msg = "Would you like to generate a new jbi.xml file right after the WSDL generation?\n"
                    + "This jbi.xml will rely on all the generated WSDL definitions.\n\n"
                    + "Please, note this will overwrite the existing one.";

            final boolean generateJbiXml = MessageDialog.openQuestion(new Shell(), "Also generate a new jbi.xml?",
                    msg);

            // Define the generation context
            WorkspaceModifyOperation op = new WorkspaceModifyOperation() {

                @Override
                protected void execute(IProgressMonitor monitor) throws CoreException, InterruptedException {

                    try {
                        monitor.beginTask("Generating Petals required files...", IProgressMonitor.UNKNOWN);
                        generateJsr181Files(javaProject, generateJbiXml, monitor);

                    } finally {
                        monitor.done();
                    }
                }
            };

            // Run it
            try {
                IProgressService ps = PlatformUI.getWorkbench().getProgressService();
                ps.busyCursorWhile(op);

            } catch (InterruptedException e) {
                // nothing

            } catch (InvocationTargetException e) {
                PetalsJsr181Plugin.log(e, IStatus.ERROR,
                        "A problem occurred while generating files for the JSR-181.");
                MessageDialog.openError(new Shell(), "Generation Error",
                        "A problem occurred while generating files for the JSR-181.\nCheck the log for more details.");
            }
        }

        return null;
    }

    /**
     * Updates the handler state from the current selection.
     * @return the first selected SU Java project, or null if the selection is not a SU Java project
     */
    private IJavaProject getSelectedJavaProject() {

        IJavaProject javaProject = null;
        try {
            final ISelection selection = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
                    .getSelection();
            Object o;
            if (selection instanceof IStructuredSelection && !selection.isEmpty()
                    && (o = ((IStructuredSelection) selection).getFirstElement()) instanceof IProject) {

                IProject p = (IProject) o;
                if (p.isAccessible() && p.hasNature(JavaCore.NATURE_ID)
                        && "petals-se-jsr181".equalsIgnoreCase(PetalsServicesProjectUtils.getComponentName(p)))
                    javaProject = JavaCore.create(p);
            }

        } catch (CoreException e) {
            PetalsJsr181Plugin.log(e, IStatus.WARNING);

        } catch (Exception e) {
            PetalsJsr181Plugin.log(e, IStatus.WARNING);
        }

        return javaProject;
    }

    /**
     * Generates files for the JSR-181.
     * <p>
     * 1. All the WSDL and XML schemas are deleted from the "jbi" directory.<br />
     * 2. Are listed all the classes contained in the project and annotated @WebService.<br />
     * 3. For each annotated class, a WSDL is generated in the "jbi" directory.<br />
     * 4. Eventually, if the option is activated, a jbi.xml is generated from all the WSDL.
     * </p>
     *
     * @param javaProject
     * @param generateJbiXml
     * @param monitor
     * @throws CoreException
     */
    public static void generateJsr181Files(IJavaProject javaProject, boolean generateJbiXml,
            IProgressMonitor monitor) throws CoreException {

        // Delete all the WSDL and XSD files from the "jbi" directory
        IFolder jbiFolder = javaProject.getProject().getFolder(PetalsConstants.LOC_RES_FOLDER);
        javaProject.getProject().refreshLocal(IResource.DEPTH_INFINITE, monitor);
        for (IResource res : jbiFolder.members()) {
            if (res instanceof IFile && (res.getName().endsWith(".wsdl") || res.getName().endsWith(".xsd")))
                res.delete(true, monitor);
        }

        // Get the classes that contain a JAX annotated service
        Map<String, String> classNameToServiceName = JaxWsUtils.getJaxAnnotatedJavaTypes(javaProject, monitor, true,
                false);

        // Create the WSDL
        Map<String, String> classNameToWsdlName = new HashMap<String, String>(classNameToServiceName.size());
        File targetDirectory = jbiFolder.getLocation().toFile();
        int generationErrorsCpt = 0;
        for (Map.Entry<String, String> entry : classNameToServiceName.entrySet()) {
            try {
                if (monitor != null && monitor.isCanceled())
                    throw new OperationCanceledException();

                JaxWsUtils.INSTANCE.generateWsdl(entry.getKey(), targetDirectory, javaProject);

                // Only store those whose were generated without error
                classNameToWsdlName.put(entry.getKey(), entry.getValue() + ".wsdl");

            } catch (IOException e) {
                PetalsJsr181Plugin.log(e, IStatus.ERROR);

            } catch (InterruptedException e) {
                PetalsJsr181Plugin.log(e, IStatus.ERROR);

            } catch (JaxWsException e) {
                generationErrorsCpt++;
                PetalsJsr181Plugin.log(e, IStatus.ERROR);
            }
        }

        jbiFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);

        // Generate the jbi.xml?
        if (generateJbiXml)
            generateJbiXml(javaProject.getProject(), classNameToWsdlName, monitor);

        ResourceUtils.selectResourceInPetalsExplorer(true, jbiFolder);

        // Report errors
        if (generationErrorsCpt != 0) {
            final String msg = generationErrorsCpt + (generationErrorsCpt > 1 ? " errors" : " error")
                    + " occurred during the generation process.\nCheck the log for more details.";

            Display.getDefault().asyncExec(new Runnable() {
                @Override
                public void run() {
                    MessageDialog.openError(new Shell(), "Generation Error", msg);
                }
            });
        }
    }

    /**
     * Generates the jbi.xml from the WSDL in the project.
     *
     * @param project the SU project
     * @param classNameToWsdlName map that associated a class name and a WSDL
     * <p>
     * Key = the qualified name of the annotated class<br />
     * Value = the WSDL file name
     * </p>
     *
     * @param monitor the progress monitor
     * @throws CoreException if the project resources could not be manipulated
     */
    public static void generateJbiXml(IProject project, Map<String, String> classNameToWsdlName,
            IProgressMonitor monitor) throws CoreException {

        // Get the generation values
        List<Jsr181Provides1x> provides = new ArrayList<Jsr181Provides1x>();
        for (Map.Entry<String, String> entry : classNameToWsdlName.entrySet()) {

            IFile wsdlFile = project.getFolder(PetalsConstants.LOC_RES_FOLDER).getFile(entry.getValue());
            if (wsdlFile.exists()) {

                URI uri = wsdlFile.getLocation().toFile().toURI();
                try {
                    List<JbiBasicBean> beans = WsdlUtils.INSTANCE.parse(uri);
                    for (JbiBasicBean bean : beans) {

                        Jsr181Provides1x jsr181Bean = new Jsr181Provides1x();

                        jsr181Bean.setEndpointName(bean.getEndpointName());
                        jsr181Bean.setServiceName(bean.getServiceName().getLocalPart());
                        jsr181Bean.setServiceNamespace(bean.getServiceName().getNamespaceURI());
                        jsr181Bean.setInterfaceName(bean.getInterfaceName().getLocalPart());
                        jsr181Bean.setInterfaceNamespace(bean.getInterfaceName().getNamespaceURI());

                        jsr181Bean.setWsdl(entry.getValue());
                        jsr181Bean.setClassName(entry.getKey());
                        provides.add(jsr181Bean);
                    }

                } catch (InvocationTargetException e) {
                    // nothing
                }
            }
        }

        // Generate and write the jbi.xml
        JbiXmlGenerationHelper genDelegate = new JbiXmlGenerationHelper();
        genDelegate.setComponentName("petals-se-jsr181");
        Jsr181Provides1x[] bps = new Jsr181Provides1x[provides.size()];
        String jbiXmlContent = genDelegate.createJbiDescriptor(provides.toArray(bps)).toString();

        IFile jbiXmlFile = project.getFile(PetalsConstants.LOC_JBI_FILE);
        if (!jbiXmlFile.exists())
            jbiXmlFile.create(new ByteArrayInputStream(jbiXmlContent.getBytes()), true, monitor);
        else
            jbiXmlFile.setContents(new ByteArrayInputStream(jbiXmlContent.getBytes()), true, true, monitor);
    }
}