package edu.mayo.cts2.framework.webapp.soap.endpoint;
import edu.mayo.cts2.framework.model.command.Page;
import edu.mayo.cts2.framework.model.command.ResolvedFilter;
import edu.mayo.cts2.framework.model.command.ResolvedReadContext;
import edu.mayo.cts2.framework.model.core.Directory;
import edu.mayo.cts2.framework.model.core.RESTResource;
import edu.mayo.cts2.framework.model.core.types.CompleteDirectory;
import edu.mayo.cts2.framework.model.directory.DirectoryResult;
import edu.mayo.cts2.framework.model.service.core.FilterComponent;
import edu.mayo.cts2.framework.model.service.core.Query;
import edu.mayo.cts2.framework.model.service.core.QueryControl;
import edu.mayo.cts2.framework.model.service.core.ReadContext;
import edu.mayo.cts2.framework.model.wsdl.SoapResolveRequest;
import edu.mayo.cts2.framework.service.profile.QueryService;
import edu.mayo.cts2.framework.service.profile.ResourceQuery;
import edu.mayo.cts2.framework.webapp.soap.directoryuri.DirectoryUriUtils;
import edu.mayo.cts2.framework.webapp.soap.directoryuri.SoapDirectoryUri;
import edu.mayo.cts2.framework.webapp.soap.directoryuri.SoapDirectoryUriRequest;
import edu.mayo.cts2.framework.webapp.soap.resolver.FilterResolver;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public abstract class AbstractQueryServiceEndpoint extends AbstractEndpoint {
private FilterResolver filterResolver = new FilterResolver();
protected <T, I> T doCount(
final QueryService queryService,
final I identifier,
final QueryControl queryControl,
ReadContext readContext) {
return null;
}
protected <T, I> T doUnion(
final QueryService queryService,
final I identifier,
final QueryControl queryControl,
ReadContext readContext) {
return null;
}
protected <T, I> T doIntersect(
final QueryService queryService,
final I identifier,
final QueryControl queryControl,
ReadContext readContext) {
return null;
}
protected <T, I> T doDifference(
final QueryService queryService,
final I identifier,
final QueryControl queryControl,
ReadContext readContext) {
return null;
}
protected <T, I> T doRestrict(
final QueryService queryService,
final I identifier,
final QueryControl queryControl,
ReadContext readContext) {
return null;
}
protected <T extends Directory> T populateDirectory(
DirectoryResult<?> result,
SoapDirectoryUriRequest<?> request,
Class<T> directoryClazz) {
boolean atEnd = result.isAtEnd();
boolean isComplete = atEnd && (request.getPage() == 0);
T directory;
try {
directory = directoryClazz.newInstance();
final Field field = ReflectionUtils.findField(directoryClazz,
"_entryList");
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
field.setAccessible(true);
return null;
}
});
ReflectionUtils.setField(field, directory, result.getEntries());
} catch (Exception e) {
throw new RuntimeException(e);
}
if (isComplete) {
directory.setComplete(CompleteDirectory.COMPLETE);
} else {
directory.setComplete(CompleteDirectory.PARTIAL);
//TODO:
}
directory.setNumEntries((long) result.getEntries().size());
directory.setHeading(new RESTResource());
directory.getHeading().setAccessDate(new Date());
directory.getHeading().setResourceRoot("soap");
directory.getHeading().setResourceURI("soap");
return directory;
}
protected interface ResponseBuilder<R,D extends Directory> {
public R buildResponse(D directory);
}
protected <D extends Directory, R> R doResolve(
final QueryService queryService,
final SoapResolveRequest request,
final Class<D> directoryClass,
final ResponseBuilder<R,D> responseBuilder) {
@SuppressWarnings("unchecked")
final SoapDirectoryUriRequest<Void> directoryUriRequest =
(SoapDirectoryUriRequest<Void>)
DirectoryUriUtils.deserialize(request.getDirectory());
SoapDirectoryUri<Void> directoryUri = directoryUriRequest.getSoapDirectoryUri();
if (directoryUri.getSetOperation() != null) {
throw new UnsupportedOperationException("Set Operations not implemented.");
}
Set<FilterComponent> filters = directoryUri.getFilterComponents();
final Set<ResolvedFilter> resolvedFilters = new HashSet<ResolvedFilter>();
if (CollectionUtils.isNotEmpty(filters)) {
for (FilterComponent filter : filters) {
Collection<ResolvedFilter> resolvedFilterCollection =
this.filterResolver.resolveFilter(filter, queryService);
resolvedFilters.addAll(resolvedFilterCollection);
}
}
//TODO: Need to abstract this for other Query Services,
//and ad Sort, etc.
DirectoryResult<?> result = queryService.getResourceSummaries(
new ResourceQuery() {
@Override
public Query getQuery() {
return null;
}
@Override
public Set<ResolvedFilter> getFilterComponent() {
return resolvedFilters;
}
@Override
public ResolvedReadContext getReadContext() {
return resolveReadContext(request.getContext());
}
},
null,
this.getPage(
directoryUriRequest.getPage(),
request.getQueryControl()));
D directory =
this.populateDirectory(
result,
directoryUriRequest,
directoryClass);
return responseBuilder.buildResponse(directory);
}
protected Page getPage(int pageNumber, QueryControl queryControl) {
Page page = new Page();
if (queryControl != null) {
page.setMaxToReturn(queryControl.getMaxToReturn().intValue());
}
page.setPage(pageNumber);
return page;
}
}