package org.activityinfo.server.command;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import org.activityinfo.legacy.client.Dispatcher;
import org.activityinfo.legacy.client.remote.AbstractDispatcher;
import org.activityinfo.legacy.shared.adapter.ResourceLocatorAdaptor;
import org.activityinfo.legacy.shared.command.Command;
import org.activityinfo.legacy.shared.command.result.CommandResult;
import org.activityinfo.model.auth.AuthenticatedUser;
import org.activityinfo.model.form.FormClass;
import org.activityinfo.model.form.FormInstance;
import org.activityinfo.model.form.FormInstanceLabeler;
import org.activityinfo.model.resource.Resource;
import org.activityinfo.model.resource.ResourceId;
import org.activityinfo.promise.Promise;
import org.activityinfo.service.lookup.ReferenceChoice;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ResourceLocatorSyncImpl implements ResourceLocatorSync {
private static final Logger LOGGER = Logger.getLogger(ResourceLocatorSyncImpl.class.getName());
private final DispatcherSync dispatcherSync;
private final Dispatcher dispatcherAsync;
private final ResourceLocatorAdaptor locatorAsync;
@Inject
public ResourceLocatorSyncImpl(DispatcherSync dispatcher) {
this.dispatcherSync = dispatcher;
this.dispatcherAsync = new AsyncDispatchAdapter();
this.locatorAsync = new ResourceLocatorAdaptor(dispatcherAsync);
}
@Override
public FormClass getFormClass(ResourceId resourceId) {
Promise<FormClass> formClass = locatorAsync.getFormClass(resourceId);
return assertResolved(formClass, resourceId.asString());
}
@Override
public FormInstance getFormInstance(ResourceId resourceId) {
Promise<FormInstance> formClass = locatorAsync.getFormInstance(resourceId);
return assertResolved(formClass, resourceId.asString());
}
@Override
public List<ReferenceChoice> getReferenceChoices(Set<ResourceId> range) {
List<FormInstance> instances = assertResolved(locatorAsync.queryInstances(range),
Joiner.on(", ").join(range));
List<ReferenceChoice> choices = Lists.newArrayList();
for(FormInstance instance : instances) {
choices.add(new ReferenceChoice(instance.getId(), FormInstanceLabeler.getLabel(instance)));
}
return choices;
}
@Override
public void persist(FormInstance formInstance) {
Promise<Void> result = locatorAsync.persist(formInstance);
assertResolved(result, formInstance.toString());
}
private <T> T assertResolved(Promise<T> result, String message) {
if(!result.isSettled()) {
throw new IllegalStateException("Promise is not resolved");
}
if(result.getState() == Promise.State.REJECTED) {
LOGGER.log(Level.SEVERE, "Failed to persist " + message, result.getException());
throw new RuntimeException(result.getException());
}
return result.get();
}
private class AsyncDispatchAdapter extends AbstractDispatcher {
@Override
public <T extends CommandResult> void execute(Command<T> command, AsyncCallback<T> callback) {
T result;
try {
result = dispatcherSync.execute(command);
} catch(Exception e) {
callback.onFailure(e);
return;
}
callback.onSuccess(result);
}
}
}