/*******************************************************************************
 * Copyright (c) 2005 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.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.webapplication.WebapplicationFactory;
import org.eclipse.jst.javaee.core.JavaeeFactory;
import org.eclipse.jst.javaee.web.WebAppVersionType;
import org.eclipse.jst.javaee.web.WebFactory;
import org.eclipse.jst.jsf.core.JSFVersion;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.Messages;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.ArchiveFile;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFLibrary;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;


/**
 * 
 */
@SuppressWarnings("deprecation")
public abstract class JSFUtils {
    /**
	 * The default name for the Faces servlet
	 */
	public static final String JSF_DEFAULT_SERVLET_NAME = "Faces Servlet"; //$NON-NLS-1$
	/**
	 * The default name of the Faces servlet class
	 */
	public static final String JSF_SERVLET_CLASS = "javax.faces.webapp.FacesServlet"; //$NON-NLS-1$
	/**
	 * The name of the context parameter used for JSF configuration files
	 */
	public static final String JSF_CONFIG_CONTEXT_PARAM = "javax.faces.CONFIG_FILES"; //$NON-NLS-1$
	
	/**
	 * The name of the context parameter used for defining the default JSP file extension
	 */
	public static final String JSF_DEFAULT_SUFFIX_CONTEXT_PARAM = "javax.faces.DEFAULT_SUFFIX"; //$NON-NLS-1$
	
	/**
	 * The path to the default application configuration file
	 */
	public static final String JSF_DEFAULT_CONFIG_PATH = "/WEB-INF/faces-config.xml";  //$NON-NLS-1$

	/**
	 * Default URL mapping to faces servlet
	 */
	public static final String JSF_DEFAULT_URL_MAPPING = "/faces/*"; //$NON-NLS-1$

	/**
	 * the key for implementation libraries in persistent properties
	 */
	public static final String PP_JSF_IMPLEMENTATION_LIBRARIES = "jsf.implementation.libraries"; //$NON-NLS-1$
	/**
	 * the key for component libraries in persistent properties
	 */
	public static final String PP_JSF_COMPONENT_LIBRARIES = "jsf.component.libraries"; //$NON-NLS-1$
	/**
	 * the key for implementation type in persistent properties
	 */
	public static final String PP_JSF_IMPLEMENTATION_TYPE = "jsf.implementation.type"; //$NON-NLS-1$

	private static final String DEFAULT_DEFAULT_MAPPING_SUFFIX = "jsp"; //$NON-NLS-1$

	/**
	 * In cases where there is no servlet mapping defined (where it can be implicit and provided
	 * by the container), this system property can be used to provide the "implicit" servlet
	 * mapping.
	 */
	private static final String SYS_PROP_SERVLET_MAPPING = "org.eclipse.jst.jsf.servletMapping"; //$NON-NLS-1$

	private final JSFVersion  _version;
    private final IModelProvider _modelProvider;
	
	/**
	 * @param version
	 * @param modelProvider 
	 */
	protected JSFUtils(final JSFVersion version, final IModelProvider modelProvider)
	{
	    _version = version;
	    _modelProvider = modelProvider;
	}
	
	/**
	 * @return the jsf version that this instance is for.
	 */
	public final JSFVersion getVersion()
    {
        return _version;
    }

	/**
	 * @param config
	 * @return servlet display name to use from wizard data model
	 */
	protected final String getDisplayName(IDataModel config) {
		String displayName = config.getStringProperty(IJSFFacetInstallDataModelProperties.SERVLET_NAME);
		if (displayName == null || displayName.trim().length() == 0)
			displayName = JSF_DEFAULT_SERVLET_NAME;
		return displayName.trim();
	}
	
	/**
	 * @param config
	 * @return servlet display name to use from wizard data model
	 */
	protected final String getServletClassname(IDataModel config) {
		String className = config.getStringProperty(IJSFFacetInstallDataModelProperties.SERVLET_CLASSNAME);
		if (className == null || className.trim().equals("")) //$NON-NLS-1$
			className = JSF_SERVLET_CLASS;
		return className.trim();
	}

	/**
	 * @return IModelProvider
	 */
	public final IModelProvider getModelProvider() {
		Object webAppObj = _modelProvider.getModelObject();
		if (webAppObj == null)
		{
			return null;
		}
		return _modelProvider;
	}

   /**
     * @param configPath
     */
    public final void createConfigFile(IPath configPath)
    {
        FileOutputStream os = null;
//        final String QUOTE = new String(new char[] { '"' });
        try {
            IPath dirPath = configPath.removeLastSegments(1);
            dirPath.toFile().mkdirs();
            File file = configPath.toFile();
            file.createNewFile();
            os = new FileOutputStream(file);
            printConfigFile(os);
        } catch (FileNotFoundException e) {
            JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorCreatingConfigFile, e);
        } catch (IOException e) {
            JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorCreatingConfigFile, e);
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorClosingConfigFile, e);
                }
            }
        }
    }
    
    /**
     * @param out
     */
    protected final void printConfigFile(final OutputStream out)
    {
        PrintWriter pw = null;
        try
        {
            pw = new PrintWriter(out);
            doVersionSpecificConfigFile(pw);
        }
        finally
        {
            if (pw != null)
            {
                pw.close();
            }
        }
    }
    
    /**
     * @param pw
     */
    public abstract void doVersionSpecificConfigFile(final PrintWriter pw);
    
    
    /**
     * @param webAppObj 
     * @return true if this going into a JavaEE (1.5 and later) or a J2EE (1.4 and earlier)
     * configured application.
     */
    public boolean isJavaEE(final Object webAppObj)
    {
      if (webAppObj instanceof org.eclipse.jst.javaee.web.WebApp)
      {
          org.eclipse.jst.javaee.web.WebApp webApp = (org.eclipse.jst.javaee.web.WebApp)webAppObj;
          return WebAppVersionType.VALUES.contains(webApp.getVersion());
      }
      return false;
    }

    /**
     * @param config
     * @return list of URL patterns from the datamodel
     */
    protected final List<String> getServletMappings(final IDataModel config) {
        final List<String> mappings = new ArrayList<String>();
        final String[] patterns = (String[])config.getProperty(IJSFFacetInstallDataModelProperties.SERVLET_URL_PATTERNS);
        if (patterns != null)
        {
            for (final String pattern : patterns)
            {
                mappings.add(pattern);
            }
        }
        return mappings;
    }
    /**
     * Does an update of the web application's config file.
     * 
     * @param webApp must be WebApp of the appropriate type.
     * @param config
     * @throws ClassCastException if webApp is not the appropriate type.
     */
    public abstract void updateWebApp(Object webApp, IDataModel config);


    /**
     * Called on a facet uninstall to remove JSF related changes.
     * @param webApp
     */
    public abstract void rollbackWebApp(Object webApp);
    
    /**
     * @param fileExtension
     * @return true if the file extension is deemed to be for a JSF.
     */
    protected boolean isValidKnownExtension(String fileExtension) {
    	//Bug 313830 - JSFUtils should use content type instead file extension in isValidKnownExtension.
    	List<String> validKnownExtensions = new ArrayList<String>();
    	for (String contentTypeId: new String[]{
    			"org.eclipse.jst.jsp.core.jspsource", //$NON-NLS-1$
    			"org.eclipse.jst.jsp.core.jspfragmentsource", //$NON-NLS-1$
    			"jsf.facelet"}) { //$NON-NLS-1$
        	IContentType contentType = Platform.getContentTypeManager().getContentType(contentTypeId);
        	if (contentType != null) {
        		String[] contentTypeExts = contentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
        		if (contentTypeExts != null) {
        			validKnownExtensions.addAll(Arrays.asList(contentTypeExts));
        		}
        	}
    	}
        if (fileExtension != null) {
        	return validKnownExtensions.contains(fileExtension);
        }
        return false;
    }

    
    /**
     * @param resource
     * @return true if the resource is deemed to be a JSF page.
     */
    protected boolean isJSFPage(IResource resource) {
        // currently always return true if resource != null.
        // need to find quick way of determining whether this is a JSF JSP Page
    	boolean isJSFPage = true;
    	if (resource == null) {
    		isJSFPage = false;
    	}
        return isJSFPage;
    }
    
    /**
     * @param webApp
     * @return the default file extension from the context param. Default is
     *         "jsp" if no context param.
     */
    protected String getDefaultSuffix(Object webApp) {
    	String contextParam = null;
    	if (webApp != null) {
	    	if(isJavaEE(webApp)) {
	    		contextParam = JEEUtils.getContextParam((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_DEFAULT_SUFFIX_CONTEXT_PARAM);
	    	}
	    	else {
	    		contextParam = J2EEUtils.getContextParam((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_DEFAULT_SUFFIX_CONTEXT_PARAM);
	    	}
    	}
    	if (contextParam == null) {
    		return getDefaultDefaultSuffix();
    	}
   		return normalizeSuffix(contextParam);
    }
    
    /**
     * @return the default value for the default mapping suffix
     */
    protected String getDefaultDefaultSuffix()
    {
        return DEFAULT_DEFAULT_MAPPING_SUFFIX;
    }

    /**
     * @param name 
     * @param value 
     * @return the 
     */
    protected final String calculateSuffix(final String name, final String value)
    {
        if (name != null
                && JSF_DEFAULT_SUFFIX_CONTEXT_PARAM.equals(name
                        .trim()))
        {
            return normalizeSuffix(value != null ? value.trim() : null);
        }
        return null;
    }

    /**
     * @param defSuffix
     * @return the suffix value with any leading dot removed
     */
    protected final String normalizeSuffix(String defSuffix)
    {
        if (defSuffix != null && defSuffix.startsWith(".")) //$NON-NLS-1$
        {
            defSuffix = defSuffix.substring(1);
        }
        return defSuffix;
    }

    /**
     * Holds all the obsolete JSF Library stuff.  This will go away post-Helios.
     * @author cbateman
     *
     */
    public static class JSFLibraryHandler
    {
        /**
         * Construct an array that hold paths for all JARs in a JSF library. 
         * 
         * @param jsfLib
         * @param logMissingJar true to log an error for each invalid JAR.
         * @return elements
         */
        public final IPath[] getJARPathforJSFLib(JSFLibrary jsfLib, boolean logMissingJar) {        
            EList archiveFiles = jsfLib.getArchiveFiles();
            int numJars = archiveFiles.size();
            IPath[] elements = new IPath[numJars];
            ArchiveFile ar = null;
            for (int i= 0; i < numJars; i++) {
                ar = (ArchiveFile)archiveFiles.get(i); 
                if ( !ar.exists() && logMissingJar ) {
                    logErroronMissingJAR(jsfLib, ar);
                }
                elements[i] = new Path(((ArchiveFile)archiveFiles.get(i)).getResolvedSourceLocation()).makeAbsolute();
            }
            return elements;
        }   
        
        private int numberofValidJar(EList archiveFiles) {
            int total = 0;
            final Iterator it = archiveFiles.iterator();
            ArchiveFile ar = null;
            while(it.hasNext()) {
                ar = (ArchiveFile) it.next();
                if (ar.exists()) {
                    total++;
                }
            }
            return total;
        }
        
        private void logErroronMissingJAR(JSFLibrary jsfLib, ArchiveFile ar) {
            String msg = NLS.bind(Messages.JSFUtils_MissingJAR, 
                            ar.getName(),
                            jsfLib.getLabel());
            JSFCorePlugin.log(IStatus.ERROR, msg);
        }
        
        /**
         * Construct an array that hold paths for all JARs in a JSF library. 
         * However, archive files that no longer exist are filtered out.  
         * 
         * @param jsfLib
         * @param logMissingJar true to log an error for each invalid JAR.
         * @return elements
         */
        public final IPath[] getJARPathforJSFLibwFilterMissingJars(JSFLibrary jsfLib, boolean logMissingJar) {
            EList archiveFiles = jsfLib.getArchiveFiles();
            int numJars = numberofValidJar(archiveFiles);
            IPath[] elements = new IPath[numJars];
            ArchiveFile ar = null;
            int idxValidJar = 0;
            for (int i= 0; i < archiveFiles.size(); i++) {
                ar = (ArchiveFile)archiveFiles.get(i); 
                if ( !ar.exists() ) {
                    if (logMissingJar) {
                        logErroronMissingJAR(jsfLib, ar);
                    }
                } else {
                    elements[idxValidJar] = new Path(((ArchiveFile)archiveFiles.get(i)).getResolvedSourceLocation()).makeAbsolute();
                    idxValidJar++;
                }
            }
            return elements;        
        }

    }
    
	/**
	 * Finds and returns a JSF Servlet definition, or null if servlet is not defined.
	 * 
	 * @param webApp
	 * @return Servlet or null
	 */    
    protected Object findJSFServlet(Object webApp) {
    	if(isJavaEE(webApp)) {
    		return JEEUtils.findServlet((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_SERVLET_CLASS);
    	}
   		return J2EEUtils.findServlet((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_SERVLET_CLASS);
    }

    /**
     * Creates servlet reference in WebApp if not present or updates servlet
     * name if found using the passed configuration.
     * 
     * @param webApp
     * @param config
     * @param servlet
     * @return Servlet servlet - if passed servlet was null, will return created
     *         servlet
     */
    protected Object createOrUpdateServletRef(final Object webApp,
            final IDataModel config, Object servlet)
    {
        String displayName = getDisplayName(config);
        String className = getServletClassname(config);
    	if(isJavaEE(webApp)) {
    		return JEEUtils.createOrUpdateServletRef((org.eclipse.jst.javaee.web.WebApp) webApp, displayName, className, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
   		return J2EEUtils.createOrUpdateServletRef((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, displayName, className, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    }

    /**
     * Creates servlet-mappings for the servlet for 2.5 WebModules or greated
     * 
     * @param webApp
     * @param urlMappingList
     *            - list of string values to be used in url-pattern for
     *            servlet-mapping
     * @param servlet
     */
    protected void setUpURLMappings(final Object webApp,
            final List<String> urlMappingList, final Object servlet)
    {
    	if(isJavaEE(webApp)) {
    		JEEUtils.setUpURLMappings((org.eclipse.jst.javaee.web.WebApp) webApp, urlMappingList, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
    	else {
    		J2EEUtils.setUpURLMappings((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, urlMappingList, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    	}
    }

	/**
	 * Removes servlet-mappings for servlet using servlet-name for >= 2.5 WebModules.
	 * @param webApp
	 * @param servlet
	 */
	protected void removeURLMappings(final Object webApp, final Object servlet) {
    	if(isJavaEE(webApp)) {
    		JEEUtils.removeURLMappings((org.eclipse.jst.javaee.web.WebApp) webApp, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
    	else {
    		J2EEUtils.removeURLMappings((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    	}
	}
	
	/**
	 * Removes servlet definition
	 * @param webApp
	 * @param servlet
	 */
	protected void removeJSFServlet(final Object webApp, final Object servlet) {
    	if(isJavaEE(webApp)) {
    		JEEUtils.removeServlet((org.eclipse.jst.javaee.web.WebApp) webApp, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
    	else {
    		J2EEUtils.removeServlet((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    	}
	}
	
    /**
     * Removes context-param
     * @param webApp
     */
    protected void removeJSFContextParams(final Object webApp) {
    	if(isJavaEE(webApp)) {
    		JEEUtils.removeContextParam((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM);
    	}
    	else {
    		J2EEUtils.removeContextParam((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM);
    	}
    }
    
	/**
	 * Creates or updates context-params
	 * @param webApp
	 * @param config
	 */
	protected void setupContextParams(final Object webApp, final IDataModel config) {
        final String paramValue = config.getStringProperty(IJSFFacetInstallDataModelProperties.CONFIG_PATH);
        if (paramValue != null && !paramValue.equals(JSF_DEFAULT_CONFIG_PATH)) {
        	if(isJavaEE(webApp)) {
        		JEEUtils.setupContextParam((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM, paramValue);
        	}
        	else {
        		J2EEUtils.setupContextParam((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM, paramValue);
        	}
        }

	}
	
    /**
     * @param map
     * @param webApp
     * @return extension from map. Will return null if file extension not found
     *         in url patterns.
     */
    protected String getFileExtensionFromMap(final Object webApp, final Object map) {
    	if(isJavaEE(webApp)) {
    		return JEEUtils.getFileExtensionFromMap((org.eclipse.jst.javaee.web.ServletMapping) map);
    	}
   		return J2EEUtils.getFileExtensionFromMap((org.eclipse.jst.j2ee.webapplication.ServletMapping) map);
    }

    /**
     * @param webApp 
     * @param map
     * @return prefix mapping. may return null.
     */
    protected String getPrefixMapping(final Object webApp, final Object map) {
    	if(isJavaEE(webApp)) {
    		return JEEUtils.getPrefixMapping((org.eclipse.jst.javaee.web.ServletMapping) map);
    	}
   		return J2EEUtils.getPrefixMapping((org.eclipse.jst.j2ee.webapplication.ServletMapping) map);
    }
    
    /**
     * @param webAppObj
     * @param resource
     * @param existingURL
     * @return the modified url path for the (possibly) jsf resource.
     */
    public IPath getFileUrlPath(Object webAppObj, IResource resource,
            IPath existingURL) {
        // if not a JSF page, do nothing
        if (!isJSFPage(resource))
        {
            return null;
        }

        Object servlet = findJSFServlet(webAppObj);
        List implicitServletMappings = new ArrayList();
        if (servlet == null)
        {
        	servlet = createImplicitServletAndMapping(webAppObj, implicitServletMappings);
        }

        String defaultSuffix = getDefaultSuffix(webAppObj);
        // is the resource using default_suffix
        String fileExtension = resource.getFileExtension();
        boolean canUseExtensionMapping = fileExtension != null && fileExtension.equalsIgnoreCase(defaultSuffix);
        // if not using default extension and is not a known file extension,
        // then we will abort
        if (!canUseExtensionMapping
                && !isValidKnownExtension(resource.getFileExtension()))
            return null;

    	if(isJavaEE(webAppObj)) {
    		org.eclipse.jst.javaee.web.WebApp webApp =  (org.eclipse.jst.javaee.web.WebApp) webAppObj;

            final String servletName = ((org.eclipse.jst.javaee.web.Servlet) servlet).getServletName();

            String foundFileExtension = null;
            List mappings;
            if (webApp.getServletMappings().size() > 0) {
            	mappings = webApp.getServletMappings();
            } else {
            	mappings = implicitServletMappings;
            }
            for (final org.eclipse.jst.javaee.web.ServletMapping map : (List<org.eclipse.jst.javaee.web.ServletMapping>) mappings)
            {
                if (map != null &&
                        map.getServletName() != null &&
                        map.getServletName().trim().equals(servletName.trim()))
                {
                    foundFileExtension = getFileExtensionFromMap(webAppObj, map);
                    if (foundFileExtension != null && canUseExtensionMapping)
                    {
                        return existingURL.removeFileExtension()
                                .addFileExtension(foundFileExtension);
                    }

                    String foundPrefixMapping = getPrefixMapping(webAppObj, map);
                    if (foundPrefixMapping != null)
                    {
                        return new Path(foundPrefixMapping).append(existingURL);
                    }
                }
            }

            if (!canUseExtensionMapping && foundFileExtension != null)
            {
                // we could prompt user that this may not work...
                // for now we will return the extension mapping
                return existingURL.removeFileExtension().addFileExtension(
                        foundFileExtension);
            }

            // we could, at this point, add a url mapping to the faces servlet,
            // or prompt user that it may be a good idea to add one... 

    	}
    	else {
            List mappings;
            if (((org.eclipse.jst.j2ee.webapplication.Servlet)servlet).getMappings().size() > 0) {
            	mappings = ((org.eclipse.jst.j2ee.webapplication.Servlet)servlet).getMappings();
            } else {
            	mappings = implicitServletMappings;
            }
            Iterator itMappings = mappings.iterator();
            org.eclipse.jst.j2ee.webapplication.ServletMapping map = null;
            String foundFileExtension = null;
            String foundPrefixMapping = null;
            while (itMappings.hasNext())
            {
                map = (org.eclipse.jst.j2ee.webapplication.ServletMapping)itMappings.next();

                foundFileExtension = getFileExtensionFromMap(webAppObj, map);
                if (foundFileExtension != null && canUseExtensionMapping) 
                {
                    return existingURL.removeFileExtension().addFileExtension(foundFileExtension);
                }
                
                if (foundPrefixMapping == null)
                {
                    foundPrefixMapping = getPrefixMapping(webAppObj, map);
                }
            }
            if (foundPrefixMapping != null)
            {
                return new Path(foundPrefixMapping).append(existingURL); 
            }
            if (! canUseExtensionMapping && foundFileExtension != null){
                //we could prompt user that this may not work...
                //for now we will return the extension mapping
                return existingURL.removeFileExtension().addFileExtension(foundFileExtension);
            }
            
            // we could, at this point, add a url mapping to the faces servlet, 
            // or prompt user that it may be a good idea to add one...

    	}
    	return null;
    }

    /**
     * This creates a servlet and servlet mapping suitable for
     * {@link #getFileUrlPath(Object, IResource, IPath)} to be able to proceed, but the returned
     * objects are not fully-initialized for any and all purposes. USE WITH CAUTION.
     *   
     * @param webApp Web App object.
     * @param mappings List to which the that the created servlet mapping will be added.
     * @return Servlet instance (and a servlet mapping added to mappings).
     */
    private Object createImplicitServletAndMapping(Object webApp, List mappings) {
    	Object servlet;
    	String sysPropServletMapping = System.getProperty(SYS_PROP_SERVLET_MAPPING);
    	if (sysPropServletMapping == null) {
    		sysPropServletMapping = JSF_DEFAULT_URL_MAPPING;
    	}
    	if (isJavaEE(webApp)) {
    		servlet = WebFactory.eINSTANCE.createServlet();
        	((org.eclipse.jst.javaee.web.Servlet)servlet).setServletName(JSF_DEFAULT_SERVLET_NAME);
        	org.eclipse.jst.javaee.web.ServletMapping mapping = WebFactory.eINSTANCE.createServletMapping();
        	mapping.setServletName(JSF_DEFAULT_SERVLET_NAME);
        	org.eclipse.jst.javaee.core.UrlPatternType pattern = JavaeeFactory.eINSTANCE.createUrlPatternType();
        	pattern.setValue(sysPropServletMapping);
        	mapping.getUrlPatterns().add(pattern);
        	mappings.add(mapping);
    	} else {
    		servlet = WebapplicationFactory.eINSTANCE.createServlet();
    		((org.eclipse.jst.j2ee.webapplication.Servlet)servlet).setServletName(JSF_DEFAULT_SERVLET_NAME);
    		org.eclipse.jst.j2ee.webapplication.ServletMapping mapping = WebapplicationFactory.eINSTANCE.createServletMapping();
    		mapping.setUrlPattern(sysPropServletMapping);
    		mappings.add(mapping);
    	}
    	return servlet;
    }

}
