Author: markt Date: Fri Jul 7 15:13:11 2017 New Revision: 1801180 URL: http://svn.apache.org/viewvc?rev=1801180&view=rev Log: FindBugs: Make use of SimpleDateFormat instances thread-safe.
Added: tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ConcurrentDateFormat.java - copied, changed from r1801005, tomcat/tc8.0.x/trunk/java/org/apache/catalina/util/ConcurrentDateFormat.java Modified: tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ResourceAttributes.java tomcat/tc7.0.x/trunk/res/findbugs/filter-false-positives.xml Copied: tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ConcurrentDateFormat.java (from r1801005, tomcat/tc8.0.x/trunk/java/org/apache/catalina/util/ConcurrentDateFormat.java) URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ConcurrentDateFormat.java?p2=tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ConcurrentDateFormat.java&p1=tomcat/tc8.0.x/trunk/java/org/apache/catalina/util/ConcurrentDateFormat.java&r1=1801005&r2=1801180&rev=1801180&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/catalina/util/ConcurrentDateFormat.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ConcurrentDateFormat.java Fri Jul 7 15:13:11 2017 @@ -14,8 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.catalina.util; +package org.apache.naming.resources; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -33,7 +34,7 @@ public class ConcurrentDateFormat { private final String format; private final Locale locale; private final TimeZone timezone; - private final Queue<SimpleDateFormat> queue = new ConcurrentLinkedQueue<>(); + private final Queue<SimpleDateFormat> queue = new ConcurrentLinkedQueue<SimpleDateFormat>(); public static final String RFC1123_DATE = "EEE, dd MMM yyyy HH:mm:ss zzz"; public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @@ -66,6 +67,16 @@ public class ConcurrentDateFormat { queue.add(sdf); return result; } + + public Date parse(String source) throws ParseException { + SimpleDateFormat sdf = queue.poll(); + if (sdf == null) { + sdf = createInstance(); + } + Date result = sdf.parse(source); + queue.add(sdf); + return result; + } private SimpleDateFormat createInstance() { SimpleDateFormat sdf = new SimpleDateFormat(format, locale); Modified: tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ResourceAttributes.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ResourceAttributes.java?rev=1801180&r1=1801179&r2=1801180&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ResourceAttributes.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/ResourceAttributes.java Fri Jul 7 15:13:11 2017 @@ -5,15 +5,15 @@ * The ASF licenses this file to You 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 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ package org.apache.naming.resources; @@ -32,149 +32,161 @@ import javax.naming.directory.BasicAttri /** * Attributes implementation. - * + * * @author <a href="mailto:r...@apache.org">Remy Maucherat</a> */ public class ResourceAttributes implements Attributes { - - + + // -------------------------------------------------------------- Constants - + private static final long serialVersionUID = 1L; - + // Default attribute names - + /** * Creation date. */ public static final String CREATION_DATE = "creationdate"; - - + + /** * Creation date. */ public static final String ALTERNATE_CREATION_DATE = "creation-date"; - - + + /** * Last modification date. */ public static final String LAST_MODIFIED = "getlastmodified"; - - + + /** * Last modification date. */ public static final String ALTERNATE_LAST_MODIFIED = "last-modified"; - - + + /** * Name. */ public static final String NAME = "displayname"; - - + + /** * Type. */ public static final String TYPE = "resourcetype"; - - + + /** * Type. */ public static final String ALTERNATE_TYPE = "content-type"; - - + + /** * MIME type of the content. */ public static final String CONTENT_TYPE = "getcontenttype"; - - + + /** * Content length. */ public static final String CONTENT_LENGTH = "getcontentlength"; - - + + /** * Content length. */ public static final String ALTERNATE_CONTENT_LENGTH = "content-length"; - - + + /** * ETag. */ public static final String ETAG = "getetag"; - - + + /** * ETag. */ public static final String ALTERNATE_ETAG = "etag"; - - + + /** * Collection type. */ public static final String COLLECTION_TYPE = "<collection/>"; - - + + /** * HTTP date format. + * + * @deprecated Not thread safe. + * Use {@link ConcurrentDateFormat#formatRfc1123(Date)}. */ + @Deprecated protected static final SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); - - + + /** * Date formats using for Date parsing. + * + * @deprecated Not thread safe. Use {@link ConcurrentDateFormat}. */ + @Deprecated protected static final SimpleDateFormat formats[] = { new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) }; - - + + protected static final TimeZone gmtZone = TimeZone.getTimeZone("GMT"); + private static final ConcurrentDateFormat concurrentFormats[] = { + new ConcurrentDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US, gmtZone), + new ConcurrentDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US, gmtZone), + new ConcurrentDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US, gmtZone) + }; + + /** * GMT timezone - all HTTP dates are on GMT */ static { - format.setTimeZone(gmtZone); formats[0].setTimeZone(gmtZone); formats[1].setTimeZone(gmtZone); formats[2].setTimeZone(gmtZone); - } // ----------------------------------------------------------- Constructors - - + + /** * Default constructor. */ public ResourceAttributes() { // NO-OP } - - + + /** * Merges with another attribute set. */ public ResourceAttributes(Attributes attributes) { this.attributes = attributes; } - - + + // ----------------------------------------------------- Instance Variables @@ -213,18 +225,18 @@ public class ResourceAttributes implemen */ protected Date lastModifiedDate = null; - + /** * Last modified date in HTTP format. */ protected String lastModifiedHttp = null; - + /** * MIME type. */ protected String mimeType = null; - + /** * Name. @@ -263,8 +275,8 @@ public class ResourceAttributes implemen return (collection); } } - - + + /** * Set collection flag. * @@ -279,11 +291,11 @@ public class ResourceAttributes implemen attributes.put(TYPE, value); } } - - + + /** * Get content length. - * + * * @return content length value */ public long getContentLength() { @@ -310,11 +322,11 @@ public class ResourceAttributes implemen } return contentLength; } - - + + /** * Set content length. - * + * * @param contentLength New content length value */ public void setContentLength(long contentLength) { @@ -322,11 +334,11 @@ public class ResourceAttributes implemen if (attributes != null) attributes.put(CONTENT_LENGTH, Long.valueOf(contentLength)); } - - + + /** * Get creation time. - * + * * @return creation time value */ public long getCreation() { @@ -348,10 +360,9 @@ public class ResourceAttributes implemen String creationDateValue = value.toString(); Date result = null; // Parsing the HTTP Date - for (int i = 0; (result == null) && - (i < formats.length); i++) { + for (int i = 0; (result == null) && (i < concurrentFormats.length); i++) { try { - result = formats[i].parse(creationDateValue); + result = concurrentFormats[i].parse(creationDateValue); } catch (ParseException e) { // Ignore } @@ -368,11 +379,11 @@ public class ResourceAttributes implemen } return creation; } - - + + /** * Set creation. - * + * * @param creation New creation value * @deprecated - unused */ @@ -383,11 +394,11 @@ public class ResourceAttributes implemen if (attributes != null) attributes.put(CREATION_DATE, new Date(creation)); } - - + + /** * Get creation date. - * + * * @return Creation date value */ public Date getCreationDate() { @@ -412,10 +423,9 @@ public class ResourceAttributes implemen String creationDateValue = value.toString(); Date result = null; // Parsing the HTTP Date - for (int i = 0; (result == null) && - (i < formats.length); i++) { + for (int i = 0; (result == null) && (i < concurrentFormats.length); i++) { try { - result = formats[i].parse(creationDateValue); + result = concurrentFormats[i].parse(creationDateValue); } catch (ParseException e) { // Ignore } @@ -432,11 +442,11 @@ public class ResourceAttributes implemen } return creationDate; } - - + + /** * Creation date mutator. - * + * * @param creationDate New creation date */ public void setCreationDate(Date creationDate) { @@ -445,11 +455,11 @@ public class ResourceAttributes implemen if (attributes != null) attributes.put(CREATION_DATE, creationDate); } - - + + /** * Get last modified time. - * + * * @return lastModified time value */ public long getLastModified() { @@ -471,11 +481,9 @@ public class ResourceAttributes implemen String lastModifiedDateValue = value.toString(); Date result = null; // Parsing the HTTP Date - for (int i = 0; (result == null) && - (i < formats.length); i++) { + for (int i = 0; (result == null) && (i < concurrentFormats.length); i++) { try { - result = - formats[i].parse(lastModifiedDateValue); + result = concurrentFormats[i].parse(lastModifiedDateValue); } catch (ParseException e) { // Ignore } @@ -492,11 +500,11 @@ public class ResourceAttributes implemen } return lastModified; } - - + + /** * Set last modified. - * + * * @param lastModified New last modified value */ public void setLastModified(long lastModified) { @@ -505,11 +513,11 @@ public class ResourceAttributes implemen if (attributes != null) attributes.put(LAST_MODIFIED, new Date(lastModified)); } - - + + /** * Get lastModified date. - * + * * @return LastModified date value */ public Date getLastModifiedDate() { @@ -534,11 +542,9 @@ public class ResourceAttributes implemen String lastModifiedDateValue = value.toString(); Date result = null; // Parsing the HTTP Date - for (int i = 0; (result == null) && - (i < formats.length); i++) { + for (int i = 0; (result == null) && (i < concurrentFormats.length); i++) { try { - result = - formats[i].parse(lastModifiedDateValue); + result = concurrentFormats[i].parse(lastModifiedDateValue); } catch (ParseException e) { // Ignore } @@ -555,11 +561,11 @@ public class ResourceAttributes implemen } return lastModifiedDate; } - - + + /** * Last modified date mutator. - * + * * @param lastModifiedDate New last modified date * @deprecated - unused */ @@ -570,8 +576,8 @@ public class ResourceAttributes implemen if (attributes != null) attributes.put(LAST_MODIFIED, lastModifiedDate); } - - + + /** * @return Returns the lastModifiedHttp. */ @@ -585,13 +591,11 @@ public class ResourceAttributes implemen if (modifiedDate == null) { modifiedDate = new Date(); } - synchronized (format) { - lastModifiedHttp = format.format(modifiedDate); - } + lastModifiedHttp = ConcurrentDateFormat.formatRfc1123(modifiedDate); return lastModifiedHttp; } - - + + /** * @param lastModifiedHttp The lastModifiedHttp to set. * @deprecated - unused @@ -600,16 +604,16 @@ public class ResourceAttributes implemen public void setLastModifiedHttp(String lastModifiedHttp) { this.lastModifiedHttp = lastModifiedHttp; } - - + + /** * @return Returns the mimeType. */ public String getMimeType() { return mimeType; } - - + + /** * @param mimeType The mimeType to set. */ @@ -617,10 +621,10 @@ public class ResourceAttributes implemen this.mimeType = mimeType; } - + /** * Get name. - * + * * @return Name value */ public String getName() { @@ -642,7 +646,7 @@ public class ResourceAttributes implemen /** * Set name. - * + * * @param name New name value */ public void setName(String name) { @@ -650,11 +654,11 @@ public class ResourceAttributes implemen if (attributes != null) attributes.put(NAME, name); } - - + + /** * Get resource type. - * + * * @return String resource type */ public String getResourceType() { @@ -675,11 +679,11 @@ public class ResourceAttributes implemen } return result; } - - + + /** * Type mutator. - * + * * @param resourceType New resource type */ public void setResourceType(String resourceType) { @@ -691,8 +695,8 @@ public class ResourceAttributes implemen /** * Get ETag. - * - * @return strong ETag if available, else weak ETag. + * + * @return strong ETag if available, else weak ETag. */ public String getETag() { String result = null; @@ -722,7 +726,7 @@ public class ResourceAttributes implemen } result = weakETag; } - } + } return result; } @@ -736,19 +740,19 @@ public class ResourceAttributes implemen attributes.put(ETAG, eTag); } - + /** - * Return the canonical path of the resource, to possibly be used for + * Return the canonical path of the resource, to possibly be used for * direct file serving. Implementations which support this should override * it to return the file path. - * + * * @return The canonical path of the resource */ public String getCanonicalPath() { return null; } - - + + // ----------------------------------------------------- Attributes Methods @@ -808,8 +812,8 @@ public class ResourceAttributes implemen } return null; } - - + + /** * Put attribute. */ @@ -825,8 +829,8 @@ public class ResourceAttributes implemen return attributes.put(attribute); } } - - + + /** * Put attribute. */ @@ -838,8 +842,8 @@ public class ResourceAttributes implemen return attributes.put(attrID, val); } } - - + + /** * Remove attribute. */ @@ -851,8 +855,8 @@ public class ResourceAttributes implemen return attributes.remove(attrID); } } - - + + /** * Get all attributes. */ @@ -899,8 +903,8 @@ public class ResourceAttributes implemen return attributes.getAll(); } } - - + + /** * Get all attribute IDs. */ @@ -941,8 +945,8 @@ public class ResourceAttributes implemen return attributes.getIDs(); } } - - + + /** * Retrieves the number of attributes in the attribute set. */ @@ -961,8 +965,8 @@ public class ResourceAttributes implemen return attributes.size(); } } - - + + /** * Clone the attributes object (WARNING: fake cloning). */ @@ -970,8 +974,8 @@ public class ResourceAttributes implemen public Object clone() { return this; } - - + + /** * Case sensitivity. */ @@ -979,6 +983,6 @@ public class ResourceAttributes implemen public boolean isCaseIgnored() { return false; } - - + + } Modified: tomcat/tc7.0.x/trunk/res/findbugs/filter-false-positives.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/res/findbugs/filter-false-positives.xml?rev=1801180&r1=1801179&r2=1801180&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/res/findbugs/filter-false-positives.xml (original) +++ tomcat/tc7.0.x/trunk/res/findbugs/filter-false-positives.xml Fri Jul 7 15:13:11 2017 @@ -805,6 +805,14 @@ <Bug code="DE" /> </Match> <Match> + <Class name="org.apache.naming.resources.ResourceAttributes" /> + <Or> + <Field name="format"/> + <Field name="formats"/> + </Or> + <Bug pattern="STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE" /> + </Match> + <Match> <!-- Use of statics is unavoidable in all cases --> <!-- Better to use it consistently rather than only where necessary --> <Class name="org.apache.tomcat.jdbc.pool.interceptor.TestInterceptor" /> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org