Я пытаюсь внедрить RequestFactory и фреймворк Editor в свое приложение. Даже изучив форум, форум разработчиков Google и другие, я обнаружил, что есть что-то фундаментальное, чего я не понимаю в использовании RequestContext с RequestFactory. Вот мой сценарий:
У меня есть простой объект с тремя полями: идентификатор, версия и описание, который называется CmsObjectType. У меня есть соответствующий EntityProxy и CmsObjectTypeServiceDAO с моими операциями CRUD. Я также реализовал классы ServiceLocator и ObjectLocator. Весь этот код компилируется и запускается.
Я также создал простой тестовый пример для проверки операций CRUD, используя следующее:
public class RequestFactoryProvider {
public static CmsRequestFactory get() {
SimpleEventBus eventBus = new SimpleEventBus();
CmsRequestFactory requestFactory = RequestFactoryMagic.create(CmsRequestFactory.class);
ServiceLayer serviceLayer = ServiceLayer.create();
SimpleRequestProcessor processor = new SimpleRequestProcessor(
serviceLayer);
requestFactory.initialize(eventBus, new InProcessRequestTransport(
processor));
return requestFactory;
}
}
Тест:
public class TestCmsObjectTypeRequest extends Assert {
private static CmsRequestFactory requestFactory;
private static CmsObjectTypeRequestContext objectTypeRequest;
private Long newId;
@Before
public void setUp() {
requestFactory = RequestFactoryProvider.get();
objectTypeRequest = requestFactory.objectTypeRequest();
}
@Test
public void testEdit() {
final CmsObjectTypeProxy newType = objectTypeRequest
.create(CmsObjectTypeProxy.class);
newType.setDescription("NEW TYPE");
objectTypeRequest.persist(newType).to(new Receiver<Long>() {
@Override
public void onSuccess(Long response) {
if (response != null) {
newId = response;
assertTrue(true);
} else {
fail();
}
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
// Edit the newly created object
newType.setDescription("EDITED NEW TYPE");
objectTypeRequest.update(newType).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
//Remove it when we're done..
objectTypeRequest.delete(newType).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
System.out.println("onSuccess from delete.");
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
objectTypeRequest.fire();
}
}
Когда я создаю новый контекст запроса и связываю вызовы методов для создания, обновления и удаления, а затем вызываю fire(), он работает без проблем в приведенном выше тесте. Однако, если я попытаюсь выполнить эти вызовы по отдельности, вызвав метод, а затем fire(), у меня возникнут проблемы. Я могу вызвать функцию create(), когда Receiver возвращает идентификатор вновь созданной сущности, а затем я использую этот идентификатор для вызова find(id) и возвращаю вновь созданную сущность. До этого момента все работает нормально. Однако именно здесь я запутался. Если я попытаюсь вызвать редактирование с текущим RequestContext в методе onSuccess() приемника из find (id), я получаю сообщение об ошибке, говорящее, что контекст уже выполняется. Если я создам локальную переменную для foundProxy, а затем попытаюсь использовать новый экземпляр RequestContext для вызова requestContext.edit(foundProxy) для вновь найденного объекта, а затем вызову update(), я чаще всего получаю ошибку сервера: Ошибка сервера: Запрошенный объект недоступен на сервере. Если я не создам новый экземпляр контекста запроса, я получу исключение IllegalStateException, говорящее, что запрос уже выполняется. Вот пример теста, который, надеюсь, прояснит ситуацию:
@Test
public void testEditWOChaining() {
final CmsObjectTypeProxy newType = objectTypeRequest
.create(CmsObjectTypeProxy.class);
newType.setDescription("NEW TYPE");
objectTypeRequest.persist(newType).to(new Receiver<Long>() {
@Override
public void onSuccess(Long response) {
if (response != null) {
setNewId(response);
assertTrue(true);
} else {
fail();
}
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
}).fire();
if (newId != null) {
objectTypeRequest = requestFactory.objectTypeRequest();
objectTypeRequest.find(newId)
.to(new Receiver<CmsObjectTypeProxy>() {
@Override
public void onSuccess(CmsObjectTypeProxy response) {
if (response != null) {
foundProxy = response;
}
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
}).fire();
}
if (foundProxy != null) {
// Edit the newly created object
objectTypeRequest = requestFactory.objectTypeRequest();
CmsObjectTypeProxy editableProxy = objectTypeRequest
.edit(foundProxy);
editableProxy.setDescription("EDITED NEW TYPE");
objectTypeRequest.update(editableProxy).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
}).fire();
}
// Remove it when we're done..
objectTypeRequest.delete(foundProxy).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
System.out.println("onSuccess from delete.");
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
objectTypeRequest.fire();
}
Вот мои вопросы. Как лучше всего обрабатывать редактирование, если оно связано не с create(), а с find()? Если я попытаюсь связать поиск с обновлением, мой foundProxy будет нулевым, и ничего не обновится. Должны ли прокси оставаться привязанными к контексту, в котором они созданы, чтобы иметь возможность выполнять на них обновления? Если бы кто-нибудь мог объяснить, как это работает, или указать мне на какую-то документацию, в которой указано, что мне не хватает, я был бы признателен. Возможно ли, что это как-то связано с тем, как среда тестирования обрабатывает запросы? Я прочитал следующее, поэтому, если я что-то пропустил в них, сообщите мне: Отличное описание от tbroyer а>
Документы Google Будем очень признательны за любую помощь. Спасибо!