blob: 16493328ca996402fb0d2ef9a5a43c032d1c868f [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.launchpad.testservices.resourceprovider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.SyntheticResource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.launchpad.testservices.resourceprovider.PlanetsResourceProvider.DoesNotNeedAContext;
import org.apache.sling.spi.resource.provider.ResolverContext;
import org.apache.sling.spi.resource.provider.ResourceContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;
/** Test/example ResourceProvider that provides info about
* the Solar System's planets at /planets.
* Use /planets.tidy.-1.json to GET the whole thing.
*
* This uses the new (February 2016) spi.ResourceProvider base class.
* If you need an example based on the old ResourceProvider interface,
* see this code at svn revision 1727946.
*/
@Component
@Service(value=ResourceProvider.class)
@Properties({
@Property(name = ResourceProvider.PROPERTY_NAME, value = "Planets"),
@Property(name = ResourceProvider.PROPERTY_ROOT, value=PlanetsResourceProvider.ROOT)
})
public class PlanetsResourceProvider extends ResourceProvider<DoesNotNeedAContext> {
/** Our planet data. PlanetResource is created when resolving, as
* it points to a specific ResourceResolver. */
private static final Map<String, ValueMap> PLANETS = new HashMap<String, ValueMap>();
/** This can be configurable of course */
public static final String ROOT = "/planets";
/* Planet data from http://nineplanets.org/data.html
* (not that we care much about accuracy for this example ;-)
*/
static {
definePlanet("Mercury", 57910);
definePlanet("Venus", 108200);
definePlanet("Earth", 149600).put("comment", "Resources can each have different sets of properties");
definePlanet("Mars", 227940);
definePlanet("Jupiter", 4332);
definePlanet("Saturn", 10759);
definePlanet("Uranus", 30685);
definePlanet("Neptune", 60190);
// Add the moon to test a two-level hierarchy
final String moonPath = ROOT + "/earth/moon";
PLANETS.put(moonPath, new PlanetResource.PlanetValueMap("Moon", 384));
}
/** If this provider required a context this would be more elaborate,
* but for this simple example we don't need one.
*/
public static class DoesNotNeedAContext {
};
@Override
public Resource getResource(ResolverContext<DoesNotNeedAContext> ctx,
String path, ResourceContext resourceContext, Resource parent) {
// Synthetic resource for our root, so that /planets works
if((ROOT).equals(path)) {
return new SyntheticResource(ctx.getResourceResolver(), path, PlanetResource.RESOURCE_TYPE);
}
// Not root, return a Planet if we have one
final ValueMap data = PLANETS.get(path);
return data == null ? null : new PlanetResource(ctx.getResourceResolver(), path, data);
}
@Override
public Iterator<Resource> listChildren(ResolverContext<DoesNotNeedAContext> ctx, Resource parent) {
if(parent.getPath().startsWith(ROOT)) {
// Not the most efficient thing...good enough for this example
final List<Resource> kids = new ArrayList<Resource>();
for(Map.Entry<String, ValueMap> e : PLANETS.entrySet()) {
if(parent.getPath().equals(parentPath(e.getKey()))) {
kids.add(new PlanetResource(parent.getResourceResolver(), e.getKey(), e.getValue()));
}
}
return kids.iterator();
} else {
return null;
}
}
private static String parentPath(String path) {
final int lastSlash = path.lastIndexOf("/");
return lastSlash > 0 ? path.substring(0, lastSlash) : "";
}
private static ValueMap definePlanet(String name, int distance) {
final ValueMap valueMap = new PlanetResource.PlanetValueMap(name, distance);
PLANETS.put(ROOT + "/" + name.toLowerCase(), valueMap);
return valueMap;
}
}