| /******************************************************************************* |
| * Copyright (c) 2009, 2010 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| * yyyymmdd bug Email and other contact information |
| * -------- -------- ----------------------------------------------------------- |
| * 20091021 291954 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS: Implement JAX-RS Facet |
| * 20091106 291954 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS: Implement JAX-RS Facet |
| * 20100303 291954 kchong@ca.ibm.com - Keith Chong, JAX-RS: Implement JAX-RS Facet |
| * 20100310 304405 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS Facet : support JAX-RS 1.1 |
| * 20100319 306595 ericdp@ca.ibm.com - Eric D. Peters, several install scenarios fail for both user library & non-user library |
| * 20100413 307552 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS and Java EE 6 setup is incorrect |
| * 20100428 310905 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS facet fails to install due to NPE or runtime exception due to duplicate cp entries |
| * 20101123 330916 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS - facet install should consider Web project associated with multiple EARs |
| *******************************************************************************/ |
| package org.eclipse.jst.ws.jaxrs.core.internal.project.facet; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| 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.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.core.IClasspathAttribute; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider; |
| import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate; |
| import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil; |
| import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants; |
| import org.eclipse.jst.j2ee.model.IModelProvider; |
| import org.eclipse.jst.ws.jaxrs.core.internal.IJAXRSCoreConstants; |
| import org.eclipse.jst.ws.jaxrs.core.internal.Messages; |
| import org.eclipse.jst.ws.jaxrs.core.internal.jaxrslibraryconfig.JAXRSLibraryInternalReference; |
| import org.eclipse.jst.ws.jaxrs.core.internal.jaxrssharedlibraryconfig.SharedLibraryConfigurator; |
| import org.eclipse.jst.ws.jaxrs.core.internal.jaxrssharedlibraryconfig.SharedLibraryConfiguratorUtil; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModel; |
| import org.eclipse.wst.common.project.facet.core.IDelegate; |
| import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion; |
| |
| /** |
| * JAXRS Facet Install Delegate for WTP faceted web projects. Deals with 2.3, |
| * 2.4 and 2.5 web app models. |
| * |
| * Uses |
| * <code>com.eclispe.jst.ws.jaxrs.core.internal.project.facet.JAXRSFacetInstallDataModelProvider<code> for model |
| * <li> updates web.xml for: servlet, servlet-mapping and context-param |
| * <li> adds implementation jars to WEB-INF/lib if user requests |
| * |
| * @see org.eclipse.jst.ws.jaxrs.core.internal.project.facet.JAXRSFacetInstallDataModelProvider |
| * @since 1.0 |
| */ |
| public final class JAXRSFacetInstallDelegate implements IDelegate { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.wst.common.project.facet.core.IDelegate#execute(org.eclipse |
| * .core.resources.IProject, |
| * org.eclipse.wst.common.project.facet.core.IProjectFacetVersion, |
| * java.lang.Object, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void execute(final IProject project, final IProjectFacetVersion fv, |
| final Object cfg, final IProgressMonitor monitor) |
| throws CoreException |
| |
| { |
| |
| if (monitor != null) { |
| monitor.beginTask("", 1); //$NON-NLS-1$ |
| } |
| |
| try { |
| IDataModel config = null; |
| |
| if (cfg != null) { |
| config = (IDataModel) cfg; |
| } else { |
| throw new JAXRSFacetException( |
| Messages.JAXRSFacetInstallDelegate_InternalErr); |
| } |
| |
| // Before we do any configuration, verify that web.xml is available |
| // for update |
| IModelProvider provider = JAXRSUtils.getModelProvider(project); |
| if (provider == null) { |
| throw new JAXRSFacetException(NLS.bind( |
| Messages.JAXRSFacetInstallDelegate_ConfigErr, project |
| .getName())); |
| } else if (!(provider.validateEdit(null, null).isOK())) { |
| // checks for web.xml file being read-only and allows user to set writeable |
| if (!(provider.validateEdit(null, null).isOK())) { |
| throw new JAXRSFacetException( |
| NLS |
| .bind( |
| Messages.JAXRSFacetInstallDelegate_NonUpdateableWebXML, |
| project.getName())); //$NON-NLS-2$ |
| } |
| } |
| |
| |
| if (((LibraryInstallDelegate) config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE)) |
| .getLibraryProviderOperationConfig() instanceof JAXRSUserLibraryProviderInstallOperationConfig |
| // deploy is chosen |
| || (config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.DEPLOY_IMPLEMENTATION) != null && Boolean |
| .parseBoolean((config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.DEPLOY_IMPLEMENTATION) |
| .toString()))) |
| // don't include libraries |
| || (config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.DEPLOY_IMPLEMENTATION) != null |
| && !Boolean |
| .parseBoolean((config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.DEPLOY_IMPLEMENTATION) |
| .toString())) && (config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.SHAREDLIBRARY) == null || (config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.SHAREDLIBRARY) != null && !Boolean |
| .parseBoolean((config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.SHAREDLIBRARY) |
| .toString()))))) |
| |
| ) { |
| // either deploy is chosen, or user chosen not include |
| // libraries, or it is our shared library install delegate which |
| // handles both deploy & shared library options |
| ((LibraryInstallDelegate) config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE)) |
| .execute(new NullProgressMonitor()); |
| } else { |
| // Create JAXRS libraries by calling Library installer then |
| // appropriate SharedLibraryConfigurator |
| ((LibraryInstallDelegate) config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE)) |
| .execute(new NullProgressMonitor()); |
| if (!disableLibraryConfigSelected((LibraryInstallDelegate) config |
| .getProperty(IJAXRSFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE))) |
| createSharedLibraries(project, fv, monitor, config); |
| } |
| |
| // Update web model if necessary |
| if (config.getBooleanProperty(IJAXRSFacetInstallDataModelProperties.UPDATEDD)) |
| createServletAndModifyWebXML(project, config, monitor); |
| if (monitor != null) { |
| monitor.worked(1); |
| } |
| |
| } finally { |
| if (monitor != null) { |
| monitor.done(); |
| } |
| } |
| } |
| |
| private boolean disableLibraryConfigSelected(LibraryInstallDelegate property) { |
| return property.getLibraryProvider().getId() != null |
| && property.getLibraryProvider().getId().equals( |
| IJAXRSCoreConstants.NO_OP_LIBRARY_ID) ? true : false; |
| } |
| |
| private void createSharedLibraries(IProject project, |
| IProjectFacetVersion fv, IProgressMonitor monitor, IDataModel config) throws CoreException { |
| |
| String targetRuntimeID = config |
| .getStringProperty(IJAXRSFacetInstallDataModelProperties.TARGETRUNTIME); |
| SharedLibraryConfiguratorUtil |
| .getInstance(); |
| java.util.List<SharedLibraryConfigurator> configurators = SharedLibraryConfiguratorUtil.getConfigurators(); |
| ILibraryProvider libref = ((LibraryInstallDelegate)config.getProperty(IJAXRSFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE)).getLibraryProvider(); |
| Iterator<SharedLibraryConfigurator> sharedLibConfiguratorIterator = configurators |
| .iterator(); |
| while (sharedLibConfiguratorIterator.hasNext()) { |
| SharedLibraryConfigurator thisConfigurator = sharedLibConfiguratorIterator |
| .next(); |
| if (targetRuntimeID.equals(thisConfigurator.getRuntimeID())) { |
| IProject earProject = getEARProject(config); |
| Boolean addToEar = getAddToEar(config); |
| List<IProject> earProjects = (List<IProject>)config.getProperty(IJAXRSFacetInstallDataModelProperties.EARPROJECTS); |
| // Let's check the EARPROJECTS property first. If it's not null, then we are in the post-project creation mode |
| // and more than one EAR is referenced. |
| if (earProjects != null) { |
| // Iterate over all the referenced EAR projects and update them with shared library support |
| for (IProject ear : earProjects) |
| { |
| if (thisConfigurator.getIsSharedLibSupported(project, |
| ear, addToEar, libref.getId())) { |
| thisConfigurator.installSharedLibs(project, ear, |
| monitor, new ArrayList<String>()); |
| } |
| } |
| } else { // ....otherwise, business as usual, only one ear applies. |
| if (thisConfigurator.getIsSharedLibSupported(project, |
| earProject, addToEar, libref.getId())) { |
| thisConfigurator.installSharedLibs(project, earProject, |
| monitor, new ArrayList<String>()); |
| break; |
| } |
| } |
| } |
| |
| } |
| } |
| |
| /** |
| * @param path |
| * @param lib |
| * @return creates new IClasspathEntry with WTP dependency attribute set, if |
| * required |
| */ |
| private IClasspathEntry getNewCPEntry(final IPath path, |
| final JAXRSLibraryInternalReference lib) { |
| |
| IClasspathEntry entry = null; |
| if (lib.isCheckedToBeDeployed()) { |
| IClasspathAttribute depAttrib = JavaCore |
| .newClasspathAttribute( |
| IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, |
| ClasspathDependencyUtil.getDefaultRuntimePath(true) |
| .toString()); |
| entry = JavaCore.newContainerEntry(path, null, |
| new IClasspathAttribute[] { depAttrib }, true); |
| } else { |
| entry = JavaCore.newContainerEntry(path); |
| } |
| |
| return entry; |
| } |
| |
| // /** |
| // * @param config |
| // * @return list of URL patterns from the datamodel |
| // */ |
| // private List<String> getServletMappings(final IDataModel config) { |
| // List<String> mappings = new ArrayList<String>(); |
| // String[] patterns = (String[]) config |
| // .getProperty(IJAXRSFacetInstallDataModelProperties.SERVLET_URL_PATTERNS); |
| // for (int i = 0; i < patterns.length; i++) { |
| // String pattern = patterns[i]; |
| // mappings.add(pattern); |
| // } |
| // |
| // return mappings; |
| // } |
| |
| /** |
| * Create servlet and URL mappings and update the webapp |
| * |
| * @param project |
| * @param config |
| * @param monitor |
| */ |
| private void createServletAndModifyWebXML(final IProject project, |
| final IDataModel config, final IProgressMonitor monitor) { |
| |
| IModelProvider provider = JAXRSUtils.getModelProvider(project); |
| IPath webXMLPath = new Path("WEB-INF").append("web.xml"); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (JAXRSJEEUtils.isWebApp25or30(provider.getModelObject())) { |
| provider.modify(new UpdateWebXMLForJavaEE(project, config), |
| doesDDFileExist(project, webXMLPath) ? webXMLPath |
| : IModelProvider.FORCESAVE); |
| } else {// must be 2.3 or 2.4 |
| provider.modify(new UpdateWebXMLForJ2EE(project, config), |
| webXMLPath); |
| } |
| |
| } |
| |
| private boolean doesDDFileExist(IProject project, IPath webXMLPath) { |
| return project.getProjectRelativePath().append(webXMLPath).toFile() |
| .exists(); |
| } |
| |
| private IProject getEARProject(IDataModel config) { |
| String projName = config.getStringProperty(IJAXRSFacetInstallDataModelProperties.EARPROJECT_NAME); |
| if (projName == null || "".equals(projName)) |
| return null; |
| |
| IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject( |
| projName); |
| return project; |
| } |
| |
| private boolean getAddToEar(IDataModel config) { |
| return config.getBooleanProperty(IJAXRSFacetInstallDataModelProperties.ADD_TO_EAR); |
| } |
| |
| // private class UpdateWebXMLForJavaEE implements Runnable { |
| // private IProject project; |
| // private IDataModel config; |
| // |
| // UpdateWebXMLForJavaEE(final IProject project, final IDataModel config) { |
| // this.project = project; |
| // this.config = config; |
| // } |
| // |
| // public void run() { |
| // WebApp webApp = (WebApp) ModelProviderManager.getModelProvider( |
| // project).getModelObject(); |
| // // create or update servlet ref |
| // Servlet servlet = JAXRSJEEUtils.findJAXRSServlet(webApp);// check to |
| // // see |
| // // if already |
| // |
| // servlet = JAXRSJEEUtils.createOrUpdateServletRef(webApp, config, |
| // servlet); |
| // |
| // // init mappings |
| // List<String> listOfMappings = getServletMappings(config); |
| // JAXRSJEEUtils.setUpURLMappings(webApp, listOfMappings, servlet); |
| // |
| // } |
| // } |
| // |
| // private class UpdateWebXMLForJ2EE implements Runnable { |
| // private IProject project; |
| // private IDataModel config; |
| // |
| // UpdateWebXMLForJ2EE(IProject project, final IDataModel config) { |
| // this.project = project; |
| // this.config = config; |
| // } |
| // |
| // public void run() { |
| // org.eclipse.jst.j2ee.webapplication.WebApp webApp = (org.eclipse.jst.j2ee.webapplication.WebApp) ModelProviderManager |
| // .getModelProvider(project).getModelObject(); |
| // // create or update servlet ref |
| // org.eclipse.jst.j2ee.webapplication.Servlet servlet = JAXRSJ2EEUtils |
| // .findJAXRSServlet(webApp);// check to see |
| // // if already |
| // // present |
| // |
| // servlet = JAXRSJ2EEUtils.createOrUpdateServletRef(webApp, config, |
| // servlet); |
| // |
| // // init mappings |
| // List<String> listOfMappings = getServletMappings(config); |
| // JAXRSJ2EEUtils.setUpURLMappings(webApp, listOfMappings, servlet); |
| // |
| // } |
| // |
| // } |
| |
| } |