| /******************************************************************************* |
| * Copyright (c) 2007 Oracle Corporation. |
| * 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: |
| * Gerry Kessler - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.jst.jsf.core.internal.project.facet; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.core.IClasspathAttribute; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jst.common.project.facet.core.ClasspathHelper; |
| import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil; |
| import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants; |
| import org.eclipse.jst.j2ee.internal.J2EEVersionConstants; |
| import org.eclipse.jst.j2ee.model.IModelProvider; |
| import org.eclipse.jst.j2ee.model.ModelProviderManager; |
| import org.eclipse.jst.javaee.web.Servlet; |
| import org.eclipse.jst.javaee.web.WebApp; |
| import org.eclipse.jst.jsf.core.IJSFCoreConstants; |
| import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; |
| import org.eclipse.jst.jsf.core.internal.Messages; |
| import org.eclipse.jst.jsf.core.internal.jsflibraryconfig.JSFLibraryInternalReference; |
| import org.eclipse.jst.jsf.core.internal.jsflibraryconfig.JSFLibraryRegistryUtil; |
| import org.eclipse.jst.jsf.core.jsflibraryconfiguration.JSFLibraryConfigurationHelper; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.common.componentcore.ComponentCore; |
| 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; |
| |
| /** |
| * JSF 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.jsf.core.internal.project.facet.JSFFacetInstallDataModelProvider<code> for model |
| * <li> creates JSF configuration file if not already present. It will not attempt to upgrade or downgrade the version if there is a mismatch. |
| * <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.jsf.core.internal.project.facet.JSFFacetInstallDataModelProvider |
| * @since 1.0 |
| */ |
| public final class JSFFacetInstallDelegate 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 JSFFacetException( |
| Messages.JSFFacetInstallDelegate_InternalErr); |
| } |
| |
| //Before we do any configuration, verify that web.xml is available for update |
| IModelProvider provider = JSFUtils.getModelProvider(project); |
| if (provider == null ) { |
| throw new JSFFacetException( NLS.bind(Messages.JSFFacetInstallDelegate_ConfigErr, project.getName())); |
| } else if (!(provider.validateEdit(null, null).isOK())){ |
| if (!(provider.validateEdit(null, null).isOK())) {//checks for web.xml file being read-only and allows user to set writeable |
| throw new JSFFacetException(NLS.bind(Messages.JSFFacetInstallDelegate_NonUpdateableWebXML, project.getName())); //$NON-NLS-2$ |
| } |
| } |
| |
| // Create JSF Libs as classpath containers and set WTP dependencies |
| // as required |
| createClasspathEntries(project, fv, config, monitor); |
| |
| // Create config file |
| createConfigFile(project, fv, config, monitor); |
| |
| // Update web model |
| createServletAndModifyWebXML(project, config, monitor); |
| |
| if (monitor != null) { |
| monitor.worked(1); |
| } |
| |
| } finally { |
| if (monitor != null) { |
| monitor.done(); |
| } |
| } |
| } |
| |
| /** |
| * Adds the JSF Library references specified in the wizard to the project as |
| * classpath containers. Marks the containers as J2EE module dependencies as |
| * required |
| * |
| * @param project |
| * @param config |
| * @param monitor |
| */ |
| private void createClasspathEntries(final IProject project, final IProjectFacetVersion fv, final IDataModel config, final IProgressMonitor monitor) { |
| IJavaProject javaProject = JavaCore.create(project); |
| List cpEntries = new ArrayList(); |
| try { |
| for (int i=0;i<javaProject.getRawClasspath().length;i++){ |
| cpEntries.add(javaProject.getRawClasspath()[i]); |
| } |
| } catch (JavaModelException e) { |
| JSFCorePlugin.log(e, "Unable to read classpath"); //$NON-NLS-1$ |
| } |
| |
| IPath path, cp = null; |
| IClasspathEntry entry = null; |
| JSFLibraryInternalReference libref = null; |
| |
| //Implementation |
| if (config.getProperty(IJSFFacetInstallDataModelProperties.IMPLEMENTATION_TYPE_PROPERTY_NAME) |
| == IJSFFacetInstallDataModelProperties.IMPLEMENTATION_TYPE.USER_SPECIFIED){ |
| cp = new Path(JSFLibraryConfigurationHelper.JSF_LIBRARY_CP_CONTAINER_ID); |
| libref = (JSFLibraryInternalReference)config.getProperty(IJSFFacetInstallDataModelProperties.IMPLEMENTATION); |
| path = cp.append(new Path(libref.getID())); |
| entry = getNewCPEntry(path, libref); |
| cpEntries.add(entry); |
| } |
| |
| JSFLibraryInternalReference[] compLibs = (JSFLibraryInternalReference[])config.getProperty(IJSFFacetInstallDataModelProperties.COMPONENT_LIBRARIES); |
| for (int i=0;i<compLibs.length;i++){ |
| libref = compLibs[i]; |
| cp = new Path(JSFLibraryConfigurationHelper.JSF_LIBRARY_CP_CONTAINER_ID); |
| path = cp.append(new Path(libref.getID())); |
| entry = getNewCPEntry(path, libref); |
| if (entry != null) |
| cpEntries.add(entry); |
| } |
| |
| JSFLibraryRegistryUtil.setRawClasspath(javaProject, cpEntries, monitor); |
| |
| //allow for the raw classpath to be set from JSF Libs before setting the server supplied impl libs from the server, if available |
| if (config.getProperty(IJSFFacetInstallDataModelProperties.IMPLEMENTATION_TYPE_PROPERTY_NAME) |
| == IJSFFacetInstallDataModelProperties.IMPLEMENTATION_TYPE.SERVER_SUPPLIED) { |
| try { |
| ClasspathHelper.removeClasspathEntries(project, fv); |
| ClasspathHelper.addClasspathEntries(project, fv); |
| } catch (CoreException e) { |
| JSFCorePlugin.log(IStatus.ERROR, "Unable to add server supplied implementation to the classpath.", e);//$NON-NLS-1$ |
| } |
| } |
| |
| } |
| |
| /** |
| * @param path |
| * @param lib |
| * @return creates new IClasspathEntry with WTP dependency attribute set, if required |
| */ |
| private IClasspathEntry getNewCPEntry(final IPath path, final JSFLibraryInternalReference 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 getServletMappings(final IDataModel config) { |
| List mappings = new ArrayList(); |
| String[] patterns = (String[])config.getProperty(IJSFFacetInstallDataModelProperties.SERVLET_URL_PATTERNS); |
| for (int i = 0; i < patterns.length; i++) { |
| String pattern = patterns[i]; |
| mappings.add(pattern); |
| } |
| |
| return mappings; |
| } |
| |
| /** |
| * @param project |
| * @param jsfConfigPath |
| * @return absolute IPath to jsfConfig |
| */ |
| private IPath resolveConfigPath(final IProject project, final String jsfConfigPath) { |
| return ComponentCore.createComponent(project).getRootFolder() |
| .getUnderlyingFolder().getRawLocation().append( |
| new Path(jsfConfigPath)); |
| |
| } |
| |
| /** |
| * Create the faces configuration file. If the file already exist, then the file is left alone. |
| * @param project |
| * @param fv |
| * @param config |
| * @param monitor |
| */ |
| private void createConfigFile(final IProject project, |
| final IProjectFacetVersion fv, final IDataModel config, |
| final IProgressMonitor monitor) { |
| |
| |
| final IPath configPath = resolveConfigPath(project, config.getStringProperty(IJSFFacetInstallDataModelProperties.CONFIG_PATH)); |
| try { |
| // do not overwrite if the file exists |
| if (!configPath.toFile().exists()) { |
| final IWorkspaceRunnable op = new IWorkspaceRunnable(){ |
| public void run(IProgressMonitor monitor_inner) throws CoreException{ |
| if (shouldUseJ2EEConfig(fv)){ |
| JSFUtils11.createConfigFile(fv.getVersionString(), |
| configPath); |
| } else { |
| JSFUtils12.createConfigFile(fv.getVersionString(), |
| configPath); |
| } |
| project.refreshLocal(IResource.DEPTH_INFINITE, monitor_inner); |
| } |
| |
| private boolean shouldUseJ2EEConfig(final IProjectFacetVersion facetVersion) { |
| if (IJSFCoreConstants.FACET_VERSION_1_1.equals(facetVersion.getVersionString())) |
| { |
| return true; |
| } |
| return false; |
| } |
| }; |
| op.run(monitor); |
| } |
| } catch (CoreException e) { |
| JSFCorePlugin.log(e, "Exception occured while creating faces-config.xml");//$NON-NLS-1$ |
| } |
| |
| } |
| |
| /** |
| * 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 = JSFUtils.getModelProvider(project); |
| IPath webXMLPath = new Path("WEB-INF").append("web.xml"); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (JSFUtils12.isWebApp25(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 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 = JSFUtils12.findJSFServlet(webApp);// check to see |
| // if already |
| // No longer removing any old mappings on install - see 194919 // present |
| // if (servlet != null) { |
| // // remove old mappings |
| // JSFUtils12.removeURLMappings(webApp, servlet); |
| // } |
| |
| servlet = JSFUtils12 |
| .createOrUpdateServletRef(webApp, config, servlet); |
| |
| // init mappings |
| List listOfMappings = getServletMappings(config); |
| JSFUtils12.setUpURLMappings(webApp, listOfMappings, servlet); |
| |
| // setup context params |
| JSFUtils12.setupConfigFileContextParamForV2_5(webApp, config); |
| } |
| } |
| |
| 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 = JSFUtils11.findJSFServlet(webApp);// check to see |
| // if already |
| // present |
| |
| // No longer removing any old mappings on install - see 194919 |
| // if (servlet != null) { |
| // // remove old mappings |
| // JSFUtils11.removeURLMappings(webApp, servlet); |
| // } |
| |
| servlet = JSFUtils11 |
| .createOrUpdateServletRef(webApp, config, servlet); |
| |
| // init mappings |
| List listOfMappings = getServletMappings(config); |
| JSFUtils11.setUpURLMappings(webApp, listOfMappings, servlet); |
| |
| // setup context params |
| setupContextParams(webApp, config); |
| } |
| |
| private void setupContextParams(final org.eclipse.jst.j2ee.webapplication.WebApp webApp, final IDataModel config) { |
| if (webApp.getVersionID() == J2EEVersionConstants.WEB_2_3_ID)//shouldn't have to do it this way, but that's the way it goes 119442 |
| JSFUtils11.setupConfigFileContextParamForV2_3(webApp, config); |
| else |
| JSFUtils11.setupConfigFileContextParamForV2_4(webApp, config); |
| } |
| } |
| |
| |
| |
| } |