[579905] Use the jst.web facet to pick the default JSP supertype

         Only applies on Dynamic Web Projects. Other Java projects
         will continue to rely on what's found on the Build Path.

         Also fix the caching mechanism.

Change-Id: I677da9d8de3c59ed6dc8eee4677bf13a44a908b7
diff --git a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java
index 3365adf..3e3d3f3 100644
--- a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java
+++ b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java
@@ -72,8 +72,8 @@
  */
 public final class DeploymentDescriptorPropertyCache {
 	private static final PropertyGroup[] NO_PROPERTY_GROUPS = new PropertyGroup[0];
-	private static final String JAKARTA_SERVLET = "jakarta.servlet";
-	private static final String JAVAX_SERVLET = "javax.servlet";
+	private static final String JAKARTA_SERVLET = "jakarta.servlet"; //$NON-NLS-1$
+	private static final String JAVAX_SERVLET = "javax.servlet"; //$NON-NLS-1$
 
 	static class DeploymentDescriptor {
 		PropertyGroup[] groups;
@@ -282,6 +282,11 @@
 				if (segmentCount > 1 && path.lastSegment().equals(WEB_XML) && path.segment(segmentCount - 2).equals(WEB_INF)) {
 					getInstance().deploymentDescriptorChanged(path);
 				}
+				if ("org.eclipse.wst.common.project.facet.core.xml".equalsIgnoreCase(path.lastSegment())) { //$NON-NLS-1$
+					synchronized (LOCK) {
+						getInstance().invalidate(path.segment(0));
+					}
+				}
 			}
 			else if (resource.getType() == IResource.PROJECT && (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.REMOVED)) {
 				String name = resource.getName();
@@ -325,7 +330,7 @@
 
 		public void error(SAXParseException exception) throws SAXException {
 			if (fDoLogExceptions)
-				Logger.log(Logger.WARNING, "SAXParseException with " + fPath + " (error) while reading descriptor: " + exception.getMessage()); //$NON-NLS-1$// $NON-NLS-2$ //$NON-NLS-3$
+				Logger.log(Logger.WARNING, "SAXParseException with " + fPath + " (error) while reading descriptor: " + exception.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$// $NON-NLS-2$ //$NON-NLS-3$
 		}
 
 		public void fatalError(SAXParseException exception) throws SAXException {
@@ -720,7 +725,7 @@
 					// try determining from schema declarations
 					String schemaLocations = webapp.getAttribute(SCHEMA_LOCATION);
 					if (schemaLocations != null && schemaLocations.length() > 0) {
-						if (schemaLocations.contains("/web-app_5_0.xsd")) {
+						if (schemaLocations.contains("/web-app_5_0.xsd")) { //$NON-NLS-1$
 							version[0] = Float.valueOf(5);
 						}
 						/**
@@ -824,44 +829,55 @@
 	 *         Build Path, <code>null</code> if none was discoverable.
 	 */
 	private ServletAPIDescriptor discoverServletAPIVersion(IProject project) {
+		if (FacetModuleCoreSupport.isDynamicWebProject(project) || FacetModuleCoreSupport.isWebFragmentProject(project)) {
+			float version = FacetModuleCoreSupport.getDynamicWebProjectVersion(project);
+			if (version >= 5) {
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAKARTA_SERVLET, version));
+			}
+			if (version > 0) {
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, version));
+			}
+		}
+
 		IJavaProject javaProject = JavaCore.create(project);
 		if (!javaProject.exists()) {
 			return null;
 		}
+
 		try {
 			if (javaProject.findType("jakarta.servlet.GenericFilter") != null) { //$NON-NLS-1$
-				return new ServletAPIDescriptor(JAKARTA_SERVLET, 5);
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAKARTA_SERVLET, 5));
 			}
 			if (javaProject.findType("javax.servlet.GenericFilter") != null) { //$NON-NLS-1$
-				return new ServletAPIDescriptor(JAVAX_SERVLET, 4);
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, 4));
 			}
 			if (javaProject.findType("javax.servlet.ReadListener") != null) { //$NON-NLS-1$
-				return new ServletAPIDescriptor(JAVAX_SERVLET, 3.1f);
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, 3.1f));
 			}
 			if (javaProject.findType("javax.servlet.SessionCookieConfig") != null) { //$NON-NLS-1$
-				return new ServletAPIDescriptor(JAVAX_SERVLET, 3);
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, 3));
 			}
 			IType servletRequestType = javaProject.findType("javax.servlet.http.HttpServletRequest"); //$NON-NLS-1$
 			if (servletRequestType != null) {
 				IMethod[] methods = servletRequestType.getMethods();
 				for (int i = 0; i < methods.length; i++) {
 					if ("getContextPath".equals(methods[i].getElementName())) { //$NON-NLS-1$
-						return new ServletAPIDescriptor(JAVAX_SERVLET, 2.5f);
+						return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, 2.5f));
 					}
 				}
 			}
 			if (javaProject.findType("javax.servlet.ServletRequestAttributeEvent") != null) { //$NON-NLS-1$
-				return new ServletAPIDescriptor(JAVAX_SERVLET, 2.4f);
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, 2.4f));
 			}
 			if (javaProject.findType("javax.servlet.Filter") != null) { //$NON-NLS-1$
-				return new ServletAPIDescriptor(JAVAX_SERVLET, 2.3f);
+				return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, 2.3f));
 			}
 			if (javaProject.findType("javax.servlet.http.HttpServletResponse") != null) { //$NON-NLS-1$
 				if (servletRequestType != null) {
 					IField[] fields = servletRequestType.getFields();
 					for (int i = 0; i < fields.length; i++) {
 						if ("SC_REQUESTED_RANGE_NOT_SATISFIABLE".equals(fields[i].getElementName())) { //$NON-NLS-1$
-							return new ServletAPIDescriptor(JAVAX_SERVLET, 2.2f);
+							return doCacheDescriptor(project.getName(), new ServletAPIDescriptor(JAVAX_SERVLET, 2.2f));
 						}
 					}
 				}
@@ -873,6 +889,12 @@
 		return null;
 	}
 
+	private ServletAPIDescriptor doCacheDescriptor(String projectName, ServletAPIDescriptor descriptor) {
+		Reference<ServletAPIDescriptor> reference = new SoftReference<>(descriptor);
+		apiVersions.put(projectName, reference);
+		return descriptor;
+	}
+
 	/**
 	 * parse the specified resource using Xerces, and if that fails, use the
 	 * SSE XML parser to find the property groups.
diff --git a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
index f530633..40c494d 100644
--- a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
+++ b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
@@ -735,7 +735,7 @@
 		List errorTypeNames = new ArrayList(2);
 		if (!isTypeFound(decodeType(fSuperclass), errorTypeNames)) {
 			for (int i = 0; i < errorTypeNames.size(); i++) {
-				Object problem = createJSPProblem(IJSPProblem.F_PROBLEM_ID_LITERAL, IProblem.UndefinedType, MessageFormat.format(JSPCoreMessages.JSPDirectiveValidator_8, new String[]{errorTypeNames.get(i).toString()}), 0,1);
+				Object problem = createJSPProblem(IJSPProblem.F_PROBLEM_ID_LITERAL, IProblem.UndefinedType, MessageFormat.format(JSPCoreMessages.JSPDirectiveValidator_8, new String[]{errorTypeNames.get(i).toString()}), 0, 1);
 				fTranslationProblems.add(problem);
 			}
 		}
diff --git a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupport.java b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupport.java
index bda96c5..478b6d6 100755
--- a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupport.java
+++ b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupport.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2020 IBM Corporation and others.
+ * Copyright (c) 2007, 2022 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
@@ -40,7 +40,7 @@
 	static final String META_INF_RESOURCES = "META-INF/resources/"; //$NON-NLS-1$
 	static final IPath META_INF_RESOURCES_PATH = new Path(META_INF_RESOURCES);
 
-	static final float DEFAULT_SERVLET_VERSION = 4.0f;
+	static final float DEFAULT_SERVLET_VERSION = 5.0f;
 
 	/**
 	 * @param project
@@ -69,7 +69,7 @@
 
 	/**
 	 * @param project
-	 * @return the version of the JST Web facet installed on the project, -1 otherwise
+	 * @return the version of the JST Web facet installed on the project, a default otherwise
 	 * @throws org.eclipse.core.runtime.CoreException
 	 */
 	public static float getDynamicWebProjectVersion(IProject project) {
diff --git a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java
index 1ad6d42..5959fc0 100644
--- a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java
+++ b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2020 IBM Corporation and others.
+ * Copyright (c) 2007, 2022 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
@@ -58,9 +58,10 @@
 	 * @see org.eclipse.wst.common.componentcore.internal.util.IModuleConstants.JST_WEBFRAGMENT_MODULE
 	 */
 	private final static String JST_WEBFRAGMENT_MODULE = "jst.webfragment"; //$NON-NLS-1$
+
 	/**
 	 * @param project
-	 * @return the version of the JST Web facet, a default otherwise
+	 * @return the version of the JST Web facet, a default version otherwise
 	 * @throws CoreException
 	 */
 	static float getDynamicWebProjectVersion(IProject project) {
diff --git a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPJavaValidator.java b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPJavaValidator.java
index 5bf14ca..b418b2c 100644
--- a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPJavaValidator.java
+++ b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPJavaValidator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2020 IBM Corporation and others.
+ * Copyright (c) 2006, 2022 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
@@ -366,26 +366,26 @@
 								// add new Java task marker
 								try {
 									IMarker task = f.createMarker(JAVA_TASK_MARKER_TYPE);
-									task.setAttribute(IMarker.LINE_NUMBER, new Integer(m.getLineNumber()));
-									task.setAttribute(IMarker.CHAR_START, new Integer(m.getOffset()));
-									task.setAttribute(IMarker.CHAR_END, new Integer(m.getOffset() + m.getLength()));
+									task.setAttribute(IMarker.LINE_NUMBER, Integer.valueOf(m.getLineNumber()));
+									task.setAttribute(IMarker.CHAR_START, Integer.valueOf(m.getOffset()));
+									task.setAttribute(IMarker.CHAR_END, Integer.valueOf(m.getOffset() + m.getLength()));
 									task.setAttribute(IMarker.MESSAGE, m.getText());
 									task.setAttribute(IMarker.USER_EDITABLE, Boolean.FALSE);
 
 									switch (m.getSeverity()) {
 										case IMessage.HIGH_SEVERITY: {
-											task.setAttribute(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_HIGH));
-											task.setAttribute(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
+											task.setAttribute(IMarker.PRIORITY, Integer.valueOf(IMarker.PRIORITY_HIGH));
+											task.setAttribute(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_ERROR));
 										}
 											break;
 										case IMessage.LOW_SEVERITY : {
-											task.setAttribute(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_LOW));
-											task.setAttribute(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
+											task.setAttribute(IMarker.PRIORITY, Integer.valueOf(IMarker.PRIORITY_LOW));
+											task.setAttribute(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_INFO));
 										}
 											break;
 										default : {
-											task.setAttribute(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_NORMAL));
-											task.setAttribute(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
+											task.setAttribute(IMarker.PRIORITY, Integer.valueOf(IMarker.PRIORITY_NORMAL));
+											task.setAttribute(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_WARNING));
 										}
 									}
 								}