/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ package org.ebayopensource.turmeric.eclipse.maven.core.ui.actions; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.apache.maven.repository.metadata.ArtifactMetadata; import org.ebayopensource.turmeric.eclipse.buildsystem.utils.ActionUtil; import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger; import org.ebayopensource.turmeric.eclipse.maven.core.repositorysystem.IMavenOrganizationProvider; import org.ebayopensource.turmeric.eclipse.maven.core.utils.MavenCoreUtils; import org.ebayopensource.turmeric.eclipse.maven.core.utils.SOAMavenConstants; import org.ebayopensource.turmeric.eclipse.maven.core.utils.WebXMLParser; import org.ebayopensource.turmeric.eclipse.mavenapi.exception.MavenEclipseApiException; import org.ebayopensource.turmeric.eclipse.mavenapi.impl.MavenEclipseUtil; import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem; import org.ebayopensource.turmeric.eclipse.repositorysystem.core.ISOARepositorySystem; import org.ebayopensource.turmeric.eclipse.resources.model.SOAImplProject; import org.ebayopensource.turmeric.eclipse.resources.model.SOAIntfMetadata; import org.ebayopensource.turmeric.eclipse.utils.collections.ListUtil; import org.ebayopensource.turmeric.eclipse.utils.plugin.ProgressUtil; import org.ebayopensource.turmeric.eclipse.utils.plugin.WorkspaceUtil; import org.ebayopensource.turmeric.eclipse.utils.ui.UIUtil; import org.eclipse.core.resources.IFile; 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.jdt.ui.JavaElementLabelProvider; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.jdom.Document; import org.maven.ide.eclipse.core.IMavenConstants; import org.osgi.framework.Version; /** * The Class AddImplProjectToWebProject. * * @author mzang */ public class AddImplProjectToWebProject implements IObjectActionDelegate { private IStructuredSelection selection; private static final SOALogger logger = SOALogger.getLogger(); private Shell shell; private volatile boolean addParentArtifact = true; /** * Instantiates a new adds the impl project to web project. */ public AddImplProjectToWebProject() { super(); } /** * {@inheritDoc} */ @Override public void setActivePart(final IAction action, final IWorkbenchPart targetPart) { shell = targetPart.getSite().getShell(); } /** * {@inheritDoc} */ @Override public void run(final IAction action) { try { addParentArtifact = true; if (SOALogger.DEBUG) logger.entering(action, selection); if (selection == null) return; List<IProject> projects = new ArrayList<IProject>(); for (Object projectObj : selection.toArray()) { IProject project = ActionUtil.preValidateAction(projectObj, logger); if (project != null) { projects.add(project); } } if (projects.size() == 0) { return; } // for now just support one selection final IProject implProject = projects.get(0); final ISOARepositorySystem repoSystem = GlobalRepositorySystem .instanceOf().getActiveRepositorySystem(); final SOAImplProject implProj = (SOAImplProject) repoSystem .getAssetRegistry().getSOAProject(implProject); final SOAIntfMetadata intfMetadata = implProj.getMetadata() .getIntfMetadata(); String adminName = intfMetadata.getServiceName(); List<IProject> wsProjects = WorkspaceUtil .getProjectsByNature(IMavenConstants.NATURE_ID); if (wsProjects.size() == 0) { MessageDialog.openWarning(shell, "No Web Project", "There is no web project in current workspace."); return; } final Map<IProject, Model> targetProjects = new HashMap<IProject, Model>(); for (IProject wsProject : wsProjects) { try { final Model pom = MavenEclipseUtil .readPOM(wsProject); if (isValidatedTargetProject(wsProject, pom, adminName) == true) { targetProjects.put(wsProject, pom); } } catch (Exception e) { logger.warning("Error occured while processing project ->" + wsProject.getName() + ". Ignoring it", e); } } if (targetProjects.size() == 0) { MessageDialog.openWarning(shell, "No Validated Web Project", "All web projects in current workspace have added servlet: " + adminName); return; } final Model dependentPom = MavenEclipseUtil .readPOM(implProject); if (dependentPom == null) { return; } JavaElementLabelProvider labelProvider = new JavaElementLabelProvider() { @Override public String getText(Object element) { String text = super.getText(element); if (element instanceof IProject) { final Model pom = targetProjects.get((IProject)element); if (pom != null && pom.getParent() != null) { text = new StringBuilder(text).append(" - ").append(pom.getParent()).toString(); } } return text; } }; IProject selectedProject = null; ElementListSelectionDialog selectionDialog = new ElementListSelectionDialog( shell, labelProvider) { @Override protected Control createDialogArea(Composite parent) { Composite contents = (Composite) super .createDialogArea(parent); if (dependentPom.getParent() != null) { final Button button = new Button(contents, SWT.CHECK); button.setSelection(addParentArtifact); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { addParentArtifact = button.getSelection(); } }); button .setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); button.setText("Use Project's Parent Artifact - " + dependentPom.getParent()); button .setToolTipText("Automatically add the project's parent artifact to the seleted web project if it does not have a parent artifact yet."); this.fFilteredList.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Object[] data = fFilteredList.getSelection(); if (data != null && data.length > 0 && data[0] instanceof IProject) { Model pom = targetProjects.get((IProject)data[0]); if (pom != null) { button.setEnabled(pom.getParent() == null); } } } }); } return contents; } }; selectionDialog.setMessage("Please select target web project"); selectionDialog .setElements(targetProjects.keySet().toArray(new IProject[0])); selectionDialog.setTitle("Select the Target Web Project"); selectionDialog.setBlockOnOpen(true); selectionDialog.setMultipleSelection(false); if (selectionDialog.open() == Window.OK) { if (selectionDialog.getResult() != null && selectionDialog.getResult().length > 0) { selectedProject = ((IProject) selectionDialog.getResult()[0]); } } if (selectedProject == null) { return; } final IFile targetWebFile = getWebFileFromWebProject(selectedProject); if (targetWebFile == null || targetWebFile.isAccessible() == false) { return; } final IProject targetWebProject = selectedProject; final WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { @Override protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { try { monitor.beginTask("Adding Services to Web Project...", ProgressUtil.PROGRESS_STEP * 10); final IFile pomFile = MavenEclipseUtil.getPomFile(targetWebProject); pomFile.refreshLocal(IResource.DEPTH_ZERO, monitor); final Model pom = MavenEclipseUtil.readPOM(targetWebProject); ProgressUtil.progressOneStep(monitor); addServletNodeToWebProject(implProj, targetWebProject, pom, addParentArtifact, monitor); ((IMavenOrganizationProvider)repoSystem.getActiveOrganizationProvider()) .postAddingServiceToWebProjects(ListUtil.arrayList(implProject), targetWebProject, pom, monitor); } catch (Exception e) { throw new InvocationTargetException(e); } finally { WorkspaceUtil.refresh(targetWebProject, monitor); monitor.done(); } } }; try { new ProgressMonitorDialog(shell).run(true, true, operation); } catch (Exception e) { logger.error(e); UIUtil.showErrorDialog(e); } } catch (Exception e) { logger.error(e); UIUtil.showErrorDialog(e); } finally { if (SOALogger.DEBUG) logger.exiting(); } } /** * Checks if is validated target project. * * @param project the project * @param pom the pom * @param adminName the admin name * @return true, if is validated target project * @throws CoreException the core exception * @throws MavenEclipseApiException the maven eclipse api exception */ public boolean isValidatedTargetProject(IProject project, Model pom, String adminName) throws CoreException, MavenEclipseApiException { if (pom == null) { return false; } String packagingType = pom.getPackaging(); if (SOAMavenConstants.MAVEN_PACKAGING_WAR .equalsIgnoreCase(packagingType) == false) { return false; } IFile targetWebFile = getWebFileFromWebProject(project); if (targetWebFile == null || targetWebFile.isAccessible() == false) { return false; } List<String> allServlets = WebXMLParser.getServletNames(targetWebFile .getContents()); return allServlets.contains(adminName) == false; } /** * Gets the web file from web project. * * @param webProject the web project * @return the web file from web project */ public static IFile getWebFileFromWebProject(IProject webProject) { IFile webXML = webProject.getFile("src/main/webapp/WEB-INF/web.xml"); return webXML; } /** * {@inheritDoc} */ @Override public void selectionChanged(final IAction action, final ISelection selection) { this.selection = (IStructuredSelection) selection; } /** * Adds the servlet node to web project. * * @param implProj the impl proj * @param targetWebProject the target web project * @param pom the pom * @param addParentArtifact the add parent artifact * @param monitor the monitor */ public static void addServletNodeToWebProject(SOAImplProject implProj, IProject targetWebProject, Model pom, boolean addParentArtifact, IProgressMonitor monitor) { SOAIntfMetadata intfMetadata = implProj.getMetadata().getIntfMetadata(); try { String namespacePart = intfMetadata.getServiceNamespacePart(); Version version = Version.parseVersion(intfMetadata .getServiceVersion()); int majorVersion = version.getMajor(); String adminName = intfMetadata.getServiceName(); Document sourceDoc = WebXMLParser.getSourceDocument(adminName, namespacePart, majorVersion); ProgressUtil.progressOneStep(monitor); IFile targetWebFile = getWebFileFromWebProject(targetWebProject); // write to target web.xml WebXMLParser.addServletElementsToWebXML(sourceDoc, targetWebFile .getContents(), targetWebFile); ProgressUtil.progressOneStep(monitor, ProgressUtil.PROGRESS_STEP * 2); // add impl project to target project dependency final Model dependentPom = MavenEclipseUtil.readPOM(implProj .getProject()); ProgressUtil.progressOneStep(monitor); final ArtifactMetadata metadata = MavenEclipseUtil .artifactMetadata(dependentPom); Dependency dependency = MavenEclipseUtil.dependency(metadata); if (dependency == null || dependency.getGroupId() == null) { return; } if (MavenCoreUtils.findDependency(dependency.getGroupId(), dependency.getArtifactId(), pom) != null) { logger.warning("Dependency has already " + "been added skipping it->" + dependency); return; } pom.addDependency(dependency); ProgressUtil.progressOneStep(monitor); if (addParentArtifact == true && pom.getParent() == null && dependentPom.getParent() != null) { pom.setParent(dependentPom.getParent()); logger .info( "The project ", targetWebProject.getName(), " does not have a parent artifact, setting with the parent artifact from impl project->", implProj.getProject().getName()); ProgressUtil.progressOneStep(monitor); } final IFile pomFile = MavenEclipseUtil.getPomFile(targetWebProject); MavenCoreUtils.mavenEclipseAPI().writePom(pomFile, pom); ProgressUtil.progressOneStep(monitor); pomFile.refreshLocal(IResource.DEPTH_ZERO, monitor); } catch (Exception e) { logger.error(e); UIUtil.showErrorDialog(e); } } }