blob: 10b2c64b8e0429f41dd577d3dcdab9aee36a5553 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. 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.sling.servlets.resolver.internal.helper;
import java.util.Iterator;
import java.util.Set;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.servlets.ServletResolverConstants;
/**
* The <code>ResourceCollector</code> class provides a single public method -
* {@link #getServlets(ResourceResolver)} - which is used to find an ordered collection
* of <code>Resource</code> instances which may be used to find a servlet or
* script to handle a request to the given resource.
*/
public class NamedScriptResourceCollector extends AbstractResourceCollector {
private final String scriptName;
public static NamedScriptResourceCollector create(final String name,
final Resource resource,
final String[] executionPaths) {
final String resourceType;
final String resourceSuperType;
final String baseResourceType;
final String extension;
final String scriptName;
if ( resource != null ) {
resourceType = resource.getResourceType();
resourceSuperType = resource.getResourceSuperType();
baseResourceType = ServletResolverConstants.DEFAULT_RESOURCE_TYPE;
} else {
resourceType = "";
resourceSuperType = null;
baseResourceType = "";
}
scriptName = name;
final int pos = name.lastIndexOf('.');
if ( pos == -1 ) {
extension = null;
} else {
extension = name.substring(pos);
}
return new NamedScriptResourceCollector(baseResourceType,
resourceType,
resourceSuperType,
scriptName,
extension,
executionPaths);
}
public NamedScriptResourceCollector(final String baseResourceType,
final String resourceType,
final String resourceSuperType,
final String scriptName,
final String extension,
final String[] executionPaths) {
super(baseResourceType, resourceType, resourceSuperType, extension, executionPaths);
this.scriptName = scriptName;
// create the hash code once
final String key = baseResourceType + ':' + this.scriptName + ':' +
this.resourceType + ':' + (this.resourceSuperType == null ? "" : this.resourceSuperType) +
':' + (this.extension == null ? "" : this.extension);
this.hashCode = key.hashCode();
}
@Override
protected void getWeightedResources(final Set<WeightedResource> resources,
final Resource location) {
final ResourceResolver resolver = location.getResourceResolver();
// if extension is set, we first check for an exact script match
if ( this.extension != null ) {
final String path = ResourceUtil.normalize(location.getPath() + '/' + this.scriptName);
if ( this.isPathAllowed(path) ) {
final Resource current = resolver.getResource(path);
if ( current != null ) {
this.addWeightedResource(resources, current, 0, WeightedResource.WEIGHT_EXTENSION);
}
}
}
// if the script name denotes a path we have to get the denoted resource
// first
final Resource current;
final String name;
final int pos = this.scriptName.lastIndexOf('/');
if ( pos == -1 ) {
current = location;
name = this.scriptName;
} else {
current = getResource(resolver, location.getPath() + '/' + this.scriptName.substring(0, pos));
name = this.scriptName.substring(pos + 1);
}
final Iterator<Resource> children = resolver.listChildren(current);
while (children.hasNext()) {
final Resource child = children.next();
if ( !this.isPathAllowed(child.getPath()) ) {
continue;
}
final String currentScriptName = child.getName();
final int lastDot = currentScriptName.lastIndexOf('.');
if (lastDot < 0) {
// no extension in the name, this is not a script
continue;
}
if ( currentScriptName.substring(0, lastDot).equals(name) ) {
this.addWeightedResource(resources, child, 0, WeightedResource.WEIGHT_PREFIX);
}
}
}
@Override
public boolean equals(Object obj) {
if ( !(obj instanceof NamedScriptResourceCollector) ) {
return false;
}
if ( obj == this ) {
return true;
}
if ( super.equals(obj) ) {
final NamedScriptResourceCollector o = (NamedScriptResourceCollector)obj;
if ( stringEquals(scriptName, o.scriptName)) {
return true;
}
}
return false;
}
}