/*
* #%L
* FlatPack Demonstration Server
* %%
* Copyright (C) 2012 Perka Inc.
* %%
* Licensed 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.
* #L%
*/
package com.getperka.flatpack.demo.server;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import javax.ws.rs.core.Application;
import com.getperka.flatpack.Configuration;
import com.getperka.flatpack.HasUuid;
import com.getperka.flatpack.PersistenceMapper;
import com.getperka.flatpack.ext.EntityResolver;
import com.getperka.flatpack.jersey.FlatPackProvider;
import com.getperka.flatpack.jersey.FlatPackResolver;
import com.getperka.flatpack.policy.StaticPolicy;
import com.getperka.flatpack.search.SearchTypeSource;
import com.getperka.flatpack.security.SecurityPolicy;
import com.getperka.flatpack.util.FlatPackStreams;
/**
* A trivial JAX-RS application that registers a single resource and configures the FlatPack
* adapters.
*/
public class DemoApplication extends Application {
/**
* In a production system, this would typically be implemented as a query on the underlying
* database.
*/
private class FakeDatabaseResolver implements EntityResolver {
@Override
public <T extends HasUuid> T resolve(Class<T> clazz, UUID uuid) throws Exception {
return db.get(clazz, uuid);
}
}
/**
* Provides hints to the FlatPack stack about an entity's persistence state to enable sparse
* property transmission.
*/
private class FakePersistenceMapper implements PersistenceMapper {
/**
* A real implementation may have separate type hierarchies for persistent and ephemeral
* entities.
*/
@Override
public boolean canPersist(Class<? extends HasUuid> entityType) {
return true;
}
@Override
public boolean isPersisted(HasUuid entity) {
return db.isPersisted(entity);
}
}
private FakeDatabase db = new FakeDatabase();
@Override
public Set<Object> getSingletons() {
SecurityPolicy securityPolicy;
try {
securityPolicy = new StaticPolicy(FlatPackStreams.read(
new InputStreamReader(getClass().getResourceAsStream("DemoServer.policy"),
Charset.forName("UTF8"))));
} catch (IOException e) {
throw new RuntimeException("Could not load security policy file", e);
}
Set<Object> toReturn = new LinkedHashSet<Object>();
// Create the FlatPack configuration. This object adapts FlatPack behaviors to the local system.
Configuration configuration = new Configuration()
/*
* The EntityResolver is optional and is used when FlatPack deserializes a payload to
* retrieve a persistent entity to which properties in the incoming payload will be applied.
* Implementors that do not that need to manually merge incoming DTOs with persistent state
* may omit this configuration.
*/
.addEntityResolver(new FakeDatabaseResolver())
/*
* The PersistenceMapper is optional and provides the FlatPack stack with hints related to a
* entity's persistence status.
*/
.addPersistenceMapper(new FakePersistenceMapper())
/*
* At least one TypeSource is required. The TypeSources associated with a FlatPack stack
* determine the complete set of entity types that can be processed. This SearchTypeSource
* scans the classpath for HasUuid subtypes.
*/
.addTypeSource(new SearchTypeSource("com.getperka.flatpack.demo.server"))
.withSecurityPolicy(securityPolicy)
.withPrettyPrint(true)
/*
* A PrincipalMapper is optional and, if present, enables the use principal-based property
* access restrictions whereby certain Principals are allowed to mutate only specific
* entities. This can be used, for example, to ensure that a Customer can only mutate
* properties that have an @InheritPrincipal chain back to the Customer.
*/
.withPrincipalMapper(new DemoPrincipalMapper())
.withVerbose(true);
// The FlatPackResolver makes a FlatPack instance available through the Resources interface
toReturn.add(new FlatPackResolver(configuration));
// The FlatPackProvider installs MessageBodyReader/Writer behavior
toReturn.add(new FlatPackProvider());
// This is a Resource endpoint, where HTTP paths are resolved to method invocations
toReturn.add(new DemoResource(db));
return toReturn;
}
}