At first I thought that just updating the if statement would be enough, but then I realized that:
LayerInfo existing = getLayerByName( layer.getName() );
is ambiguous since layer.getName() gives an unqualified name and getLayerByName will return one anyway. I made it a for-loop in my patch, but now I am thinking that maybe we could just use {{ layer.getResource().getNamespace().getPrefix() + ":" + layer.getName() }} to get a qualified name and avoid having to iterate through the whole list.
String qualifiedName =
layer.getResource().getNamespace().getPrefix() + ":" +
layer.getName();
LayerInfo existing = getLayerByName(qualifiedName);
if ( existing != null && !existing.getId().equals( layer.getId() ) ) {
NamespaceInfo eNamespace = existing.getResource().getNamespace();
NamespaceInfo lNamespace = layer.getResource().getNamespace();
if (eNamespace.equals(lNamespace)) {
throw new IllegalArgumentException(
"Layer named '" + layer.getName() + "' already exists in " + lNamespace + ".");
}
}
And then I realized that now that existing is fully determined by the namespace and name, we actually don't need to check those values for equality. So I think the final check should look like this.
String qualifiedName =
layer.getResource().getNamespace().getPrefix() + ":" +
layer.getName();
LayerInfo existing = getLayerByName(qualifiedName);
if ( existing != null && !existing.getId().equals( layer.getId() ) ) {
throw new IllegalArgumentException(
"Layer named '" + layer.getName() + "' already exists in " + lNamespace + ".");
}
Finally, the null-check on the resource is redundant after all this. If we want to throw a custom exception there instead of a generic NPE, we should move that line to before the uniqueness check. *That* is the patch I'm attaching.
This causes failures in addLayer, I modified it to use a different resource (and thus a different name) for the new layer. I expected similar errors in the multithreaded case but don't see them - I guess changes to the name of the shared resource aren't visible to getLayerByName until after the layer is saved? Is that expected? The multithreaded test is generating a lot of layers with the same name. (I only checked with println but I think they end up all having the same name as the last one set - which you'd expect since they all delegate getName to the same resource.)
Can you give me more context about the actual problem this produces? The catalog model, or more the api does actually allow for multiple layers for one resource. See the method on Catalog:
List<LayerInfo> getLayers( ResourceInfo resource );
Which is called in a number of places. Although I understand that with layer name bound to resource name this list will generally always contain a single element. However this was designed to be a short term workaround, eventually we would like to break this.