/*
* 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.brooklyn.camp.server.rest.util;
import java.util.Map;
import javax.ws.rs.Path;
import org.apache.brooklyn.camp.CampPlatform;
import org.apache.brooklyn.camp.server.dto.ApplicationComponentDto;
import org.apache.brooklyn.camp.server.dto.ApplicationComponentTemplateDto;
import org.apache.brooklyn.camp.server.dto.AssemblyDto;
import org.apache.brooklyn.camp.server.dto.AssemblyTemplateDto;
import org.apache.brooklyn.camp.server.dto.PlatformComponentDto;
import org.apache.brooklyn.camp.server.dto.PlatformComponentTemplateDto;
import org.apache.brooklyn.camp.server.dto.PlatformDto;
import org.apache.brooklyn.camp.server.rest.resource.AbstractCampRestResource;
import org.apache.brooklyn.camp.server.rest.resource.ApplicationComponentRestResource;
import org.apache.brooklyn.camp.server.rest.resource.ApplicationComponentTemplateRestResource;
import org.apache.brooklyn.camp.server.rest.resource.AssemblyRestResource;
import org.apache.brooklyn.camp.server.rest.resource.AssemblyTemplateRestResource;
import org.apache.brooklyn.camp.server.rest.resource.PlatformComponentRestResource;
import org.apache.brooklyn.camp.server.rest.resource.PlatformComponentTemplateRestResource;
import org.apache.brooklyn.camp.server.rest.resource.PlatformRestResource;
import org.apache.brooklyn.camp.spi.AbstractResource;
import org.apache.brooklyn.camp.spi.ApplicationComponent;
import org.apache.brooklyn.camp.spi.ApplicationComponentTemplate;
import org.apache.brooklyn.camp.spi.Assembly;
import org.apache.brooklyn.camp.spi.AssemblyTemplate;
import org.apache.brooklyn.camp.spi.PlatformComponent;
import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
import org.apache.brooklyn.camp.spi.PlatformRootSummary;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Urls;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
public class DtoFactory {
private CampPlatform platform;
private String uriBase;
private UriFactory uriFactory;
public DtoFactory(CampPlatform campPlatform, String uriBase) {
this.platform = campPlatform;
this.uriBase = uriBase;
uriFactory = new UriFactory();
uriFactory.registerIdentifiableRestResource(PlatformRootSummary.class, PlatformRestResource.class);
uriFactory.registerIdentifiableRestResource(AssemblyTemplate.class, AssemblyTemplateRestResource.class);
uriFactory.registerIdentifiableRestResource(PlatformComponentTemplate.class, PlatformComponentTemplateRestResource.class);
uriFactory.registerIdentifiableRestResource(ApplicationComponentTemplate.class, ApplicationComponentTemplateRestResource.class);
uriFactory.registerIdentifiableRestResource(Assembly.class, AssemblyRestResource.class);
uriFactory.registerIdentifiableRestResource(PlatformComponent.class, PlatformComponentRestResource.class);
uriFactory.registerIdentifiableRestResource(ApplicationComponent.class, ApplicationComponentRestResource.class);
}
public CampPlatform getPlatform() {
return platform;
}
public UriFactory getUriFactory() {
return uriFactory;
}
public String uri(AbstractResource x) {
return getUriFactory().uri(x);
}
public String uri(Class<? extends AbstractResource> targetType, String id) {
return getUriFactory().uri(targetType, id);
}
public AssemblyTemplateDto adapt(AssemblyTemplate assemblyTemplate) {
return AssemblyTemplateDto.newInstance(this, assemblyTemplate);
}
public PlatformComponentTemplateDto adapt(PlatformComponentTemplate platformComponentTemplate) {
return PlatformComponentTemplateDto.newInstance(this, platformComponentTemplate);
}
public ApplicationComponentTemplateDto adapt(ApplicationComponentTemplate applicationComponentTemplate) {
return ApplicationComponentTemplateDto.newInstance(this, applicationComponentTemplate);
}
public AssemblyDto adapt(Assembly assembly) {
return AssemblyDto.newInstance(this, assembly);
}
public PlatformComponentDto adapt(PlatformComponent platformComponent) {
return PlatformComponentDto.newInstance(this, platformComponent);
}
public ApplicationComponentDto adapt(ApplicationComponent applicationComponent) {
return ApplicationComponentDto.newInstance(this, applicationComponent);
}
public PlatformDto adapt(PlatformRootSummary root) {
return PlatformDto.newInstance(this, root);
}
public class UriFactory {
/** registry of generating a URI given an object */
Map<Class<?>,Function<Object,String>> registryResource = new MutableMap<Class<?>, Function<Object,String>>();
/** registry of generating a URI given an ID */
Map<Class<?>,Function<String,String>> registryId = new MutableMap<Class<?>, Function<String,String>>();
/** registers a function which generates a URI given a type; note that this method cannot be used for links */
@SuppressWarnings("unchecked")
public synchronized <T> void registerResourceUriFunction(Class<T> type, Function<T,String> fnUri) {
registryResource.put(type, (Function<Object, String>) fnUri);
}
/** registers a type to generate a URI which concatenates the given base with the
* result of the given function to generate an ID against an object of the given type */
public synchronized <T> void registerIdentityFunction(Class<T> type, final String resourceTypeUriBase, final Function<T,String> fnIdentity) {
final Function<String,String> fnUriFromId = new Function<String,String>() {
public String apply(String id) {
return Urls.mergePaths(resourceTypeUriBase, id);
}
};
registryId.put(type, (Function<String, String>) fnUriFromId);
registerResourceUriFunction(type, new Function<T,String>() {
public String apply(T input) {
return fnUriFromId.apply(fnIdentity.apply(input));
}
});
}
/** registers a CAMP Resource type against a RestResource, generating the URI
* by concatenating the @Path annotation on the RestResource with the ID of the CAMP resource */
@SuppressWarnings({ "unchecked", "rawtypes" })
public synchronized <T extends AbstractResource> void registerIdentifiableRestResource(Class<T> type, Class<? extends AbstractCampRestResource> restResource) {
registerIdentityFunction(type,
uriOfRestResource(restResource),
(Function) CampRestGuavas.IDENTITY_OF_REST_RESOURCE);
}
public String uri(Class<? extends AbstractResource> targetType, String id) {
return Preconditions.checkNotNull(registryId.get(targetType),
"No REST ID converter registered for %s (id %s)", targetType, id)
.apply(id);
}
public String uri(AbstractResource x) {
return Preconditions.checkNotNull(registryResource.get(x.getClass()),
"No REST converter registered for %s (%s)", x.getClass(), x)
.apply(x);
}
public String uriOfRestResource(Class<?> restResourceClass) {
return Urls.mergePaths(uriBase,
Preconditions.checkNotNull(restResourceClass.getAnnotation(Path.class),
"No @Path on type %s", restResourceClass)
.value());
}
}
}