You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2015/05/29 16:01:59 UTC
svn commit: r1682475 - in
/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal:
registry/ErrorPageRegistry.java registry/ServletRegistry.java
runtime/dto/ListenerDTOBuilder.java
Author: cziegeler
Date: Fri May 29 14:01:58 2015
New Revision: 1682475
URL: http://svn.apache.org/r1682475
Log:
Make sure, arrays for DTOs are always a copy
Modified:
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java?rev=1682475&r1=1682474&r2=1682475&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java Fri May 29 14:01:58 2015
@@ -17,6 +17,7 @@
package org.apache.felix.http.base.internal.registry;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -530,8 +531,8 @@ public final class ErrorPageRegistry
for(final Map.Entry<Integer, ErrorRegistration> entry : status.reasonMapping.entrySet())
{
final ErrorPageDTO state = ErrorPageDTOBuilder.build(status.getHandler(), entry.getKey());
- state.errorCodes = entry.getValue().errorCodes;
- state.exceptions = entry.getValue().exceptions;
+ state.errorCodes = Arrays.copyOf(entry.getValue().errorCodes, entry.getValue().errorCodes.length);
+ state.exceptions = Arrays.copyOf(entry.getValue().exceptions, entry.getValue().exceptions.length);
if ( entry.getKey() == -1 )
{
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java?rev=1682475&r1=1682474&r2=1682475&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java Fri May 29 14:01:58 2015
@@ -17,6 +17,7 @@
package org.apache.felix.http.base.internal.registry;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -25,6 +26,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nonnull;
@@ -50,25 +52,16 @@ public final class ServletRegistry
private final Map<String, List<ServletHandler>> inactiveServletMappings = new HashMap<String, List<ServletHandler>>();
- private final Map<ServletInfo, ServletRegistrationStatus> statusMapping = new ConcurrentHashMap<ServletInfo, ServletRegistry.ServletRegistrationStatus>();
-
private final Map<String, List<ServletHandler>> servletsByName = new ConcurrentHashMap<String, List<ServletHandler>>();
- public static final class ServletRegistrationStatus
- {
- public final Map<String, Integer> pathToStatus = new ConcurrentHashMap<String, Integer>();
- public ServletHandler handler;
- }
-
-/*
- public static final class RegistrationStatus
+ private static final class RegistrationStatus
{
public ServletHandler handler;
public Map<Integer, String[]> statusToPath = new HashMap<Integer, String[]>();
}
- public volatile Map<ServletInfo, RegistrationStatus> mapping = Collections.emptyMap();
-*/
+ private volatile Map<ServletInfo, RegistrationStatus> mapping = Collections.emptyMap();
+
/**
* Resolve a request uri
*
@@ -114,9 +107,11 @@ public final class ServletRegistry
// Can be null in case of error-handling servlets...
if ( handler.getServletInfo().getPatterns() != null )
{
+ final Map<ServletInfo, RegistrationStatus> newMap = new TreeMap<ServletInfo, ServletRegistry.RegistrationStatus>(this.mapping);
+
final List<PathResolver> resolvers = new ArrayList<PathResolver>(this.activeResolvers);
- final ServletRegistrationStatus status = new ServletRegistrationStatus();
+ final RegistrationStatus status = new RegistrationStatus();
status.handler = handler;
boolean isActive = false;
@@ -141,7 +136,12 @@ public final class ServletRegistry
final String oldName = regHandler.getServletHandler().getName();
regHandler.getServletHandler().destroy();
- this.addToInactiveList(pattern, regHandler.getServletHandler(), this.statusMapping.get(regHandler.getServletHandler().getServletInfo()));
+ final RegistrationStatus oldStatus = newMap.get(regHandler.getServletHandler().getServletInfo());
+ final RegistrationStatus newOldStatus = new RegistrationStatus();
+ newOldStatus.handler = oldStatus.handler;
+ newOldStatus.statusToPath = new HashMap<Integer, String[]>(oldStatus.statusToPath);
+ newMap.put(regHandler.getServletHandler().getServletInfo(), newOldStatus);
+ this.addToInactiveList(pattern, regHandler.getServletHandler(), newOldStatus);
if ( regHandler.getServletHandler().getServlet() == null )
{
@@ -164,13 +164,14 @@ public final class ServletRegistry
}
}
}
- this.statusMapping.put(handler.getServletInfo(), status);
+ newMap.put(handler.getServletInfo(), status);
if ( isActive )
{
addToNameMapping(handler);
}
Collections.sort(resolvers);
this.activeResolvers = resolvers;
+ this.mapping = newMap;
}
}
@@ -235,7 +236,9 @@ public final class ServletRegistry
{
final List<PathResolver> resolvers = new ArrayList<PathResolver>(this.activeResolvers);
- this.statusMapping.remove(info);
+ final Map<ServletInfo, RegistrationStatus> newMap = new TreeMap<ServletInfo, ServletRegistry.RegistrationStatus>(this.mapping);
+ newMap.remove(info);
+
ServletHandler cleanupHandler = null;
// used for detecting duplicates
@@ -265,7 +268,13 @@ public final class ServletRegistry
{
final ServletHandler h = inactiveList.remove(0);
boolean activate = h.getServlet() == null;
- done = this.tryToActivate(resolvers, pattern, h, this.statusMapping.get(h.getServletInfo()), regHandler);
+ final RegistrationStatus oldStatus = newMap.get(h.getServletInfo());
+ final RegistrationStatus newOldStatus = new RegistrationStatus();
+ newOldStatus.handler = oldStatus.handler;
+ newOldStatus.statusToPath = new HashMap<Integer, String[]>(oldStatus.statusToPath);
+ newMap.put(h.getServletInfo(), newOldStatus);
+ removePattern(newOldStatus, DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, pattern);
+ done = this.tryToActivate(resolvers, pattern, h, newOldStatus, regHandler);
if ( !done )
{
done = inactiveList.isEmpty();
@@ -310,6 +319,7 @@ public final class ServletRegistry
Collections.sort(resolvers);
this.activeResolvers = resolvers;
+ this.mapping = newMap;
if ( cleanupHandler != null )
{
@@ -323,10 +333,10 @@ public final class ServletRegistry
this.activeResolvers = Collections.emptyList();
this.inactiveServletMappings.clear();
this.servletsByName.clear();
- this.statusMapping.clear();
+ this.mapping = Collections.emptyMap();
}
- private void addToInactiveList(final String pattern, final ServletHandler handler, final ServletRegistrationStatus status)
+ private void addToInactiveList(final String pattern, final ServletHandler handler, final RegistrationStatus status)
{
List<ServletHandler> inactiveList = this.inactiveServletMappings.get(pattern);
if ( inactiveList == null )
@@ -336,13 +346,14 @@ public final class ServletRegistry
}
inactiveList.add(handler);
Collections.sort(inactiveList);
- status.pathToStatus.put(pattern, DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ removePattern(status, -1, pattern);
+ addPattern(status, DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, pattern);
}
private boolean tryToActivate(final List<PathResolver> resolvers,
final String pattern,
final ServletHandler handler,
- final ServletRegistrationStatus status,
+ final RegistrationStatus status,
final PathResolver oldResolver)
{
// add to active
@@ -355,16 +366,45 @@ public final class ServletRegistry
}
final PathResolver resolver = PathResolverFactory.createPatternMatcher(handler, pattern);
resolvers.add(resolver);
+ }
+ // update status
+ addPattern(status, result, pattern);
+ return result == -1;
+ }
- // add ok
- status.pathToStatus.put(pattern, result);
- return true;
+ private void addPattern(final RegistrationStatus status, final int failureCode, final String pattern)
+ {
+ String[] paths = status.statusToPath.get(failureCode);
+ if ( paths == null )
+ {
+ status.statusToPath.put(failureCode, new String[] {pattern});
}
else
{
- // add to failure
- status.pathToStatus.put(pattern, result);
- return false;
+ final String[] newPaths = new String[paths.length + 1];
+ System.arraycopy(paths, 0, newPaths, 0, paths.length);
+ newPaths[paths.length] = pattern;
+ status.statusToPath.put(failureCode, newPaths);
+ }
+ }
+
+ private void removePattern(final RegistrationStatus status, final int failureCode, final String pattern)
+ {
+ String[] paths = status.statusToPath.get(failureCode);
+ if ( paths != null )
+ {
+ final List<String> array = new ArrayList<String>(Arrays.asList(paths));
+ if ( array.remove(pattern) )
+ {
+ if ( array.isEmpty() )
+ {
+ status.statusToPath.remove(failureCode);
+ }
+ else
+ {
+ status.statusToPath.put(failureCode, array.toArray(new String[array.size()]));
+ }
+ }
}
}
@@ -389,66 +429,35 @@ public final class ServletRegistry
final Map<Long, FailedServletDTO> failedServletDTOs = new HashMap<Long, FailedServletDTO>();
final Map<Long, FailedResourceDTO> failedResourceDTOs = new HashMap<Long, FailedResourceDTO>();
- // TODO we could already do some pre calculation in the ServletRegistrationStatus
- for(final Map.Entry<ServletInfo, ServletRegistrationStatus> entry : statusMapping.entrySet())
+ for(final Map.Entry<ServletInfo, RegistrationStatus> entry : mapping.entrySet())
{
final long serviceId = entry.getKey().getServiceId();
- for(final Map.Entry<String, Integer> map : entry.getValue().pathToStatus.entrySet())
+ for(final Map.Entry<Integer, String[]> map : entry.getValue().statusToPath.entrySet())
{
- if ( !entry.getKey().isResource() )
+ if ( entry.getKey().isResource() )
{
- ServletDTO state = (map.getValue() == -1 ? servletDTOs.get(serviceId) : failedServletDTOs.get(serviceId));
- if ( state == null )
- {
- state = ServletDTOBuilder.build(entry.getValue().handler, map.getValue());
- if ( map.getValue() == -1 )
- {
- servletDTOs.put(serviceId, state);
- }
- else
- {
- failedServletDTOs.put(serviceId, (FailedServletDTO)state);
- }
- }
- String[] patterns = state.patterns;
- if ( patterns.length == 0 )
+ final ResourceDTO state = ResourceDTOBuilder.build(entry.getValue().handler, map.getKey());
+ state.patterns = Arrays.copyOf(map.getValue(), map.getValue().length);
+ if ( map.getKey() == -1 )
{
- state.patterns = new String[] {map.getKey()};
+ resourceDTOs.put(serviceId, state);
}
else
{
- patterns = new String[patterns.length + 1];
- System.arraycopy(state.patterns, 0, patterns, 0, patterns.length - 1);
- patterns[patterns.length - 1] = map.getKey();
- state.patterns = patterns;
+ failedResourceDTOs.put(serviceId, (FailedResourceDTO)state);
}
}
else
{
- ResourceDTO state = (map.getValue() == -1 ? resourceDTOs.get(serviceId) : failedResourceDTOs.get(serviceId));
- if ( state == null )
- {
- state = ResourceDTOBuilder.build(entry.getValue().handler, map.getValue());
- if ( map.getValue() == -1 )
- {
- resourceDTOs.put(serviceId, state);
- }
- else
- {
- failedResourceDTOs.put(serviceId, (FailedResourceDTO)state);
- }
- }
- String[] patterns = state.patterns;
- if ( patterns.length == 0 )
+ final ServletDTO state = ServletDTOBuilder.build(entry.getValue().handler, map.getKey());
+ state.patterns = Arrays.copyOf(map.getValue(), map.getValue().length);
+ if ( map.getKey() == -1 )
{
- state.patterns = new String[] {map.getKey()};
+ servletDTOs.put(serviceId, state);
}
else
{
- patterns = new String[patterns.length + 1];
- System.arraycopy(state.patterns, 0, patterns, 0, patterns.length - 1);
- patterns[patterns.length - 1] = map.getKey();
- state.patterns = patterns;
+ failedServletDTOs.put(serviceId, (FailedServletDTO)state);
}
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java?rev=1682475&r1=1682474&r2=1682475&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java Fri May 29 14:01:58 2015
@@ -18,6 +18,8 @@
*/
package org.apache.felix.http.base.internal.runtime.dto;
+import java.util.Arrays;
+
import org.apache.felix.http.base.internal.handler.ListenerHandler;
import org.apache.felix.http.base.internal.runtime.ListenerInfo;
import org.osgi.service.http.runtime.dto.FailedListenerDTO;
@@ -30,7 +32,7 @@ public final class ListenerDTOBuilder
final ListenerDTO dto = (reason == -1 ? new ListenerDTO() : new FailedListenerDTO());
dto.serviceId = info.getServiceId();
- dto.types = info.getListenerTypes();
+ dto.types = Arrays.copyOf(info.getListenerTypes(), info.getListenerTypes().length);
if ( reason != -1 )
{