use of it.niedermann.nextcloud.deck.api.IResponseCallback in project nextcloud-deck by stefan-niedermann.
the class SyncManager method createFullCard.
// public LiveData<FullCard> createCard(long accountId, long localBoardId, long localStackId, Card card) {
//
// MutableLiveData<FullCard> liveData = new MutableLiveData<>();
// executor.submit(() -> {
// Account account = dataBaseAdapter.getAccountByIdDirectly(accountId);
// User owner = dataBaseAdapter.getUserByUidDirectly(accountId, account.getUserName());
// FullStack stack = dataBaseAdapter.getFullStackByLocalIdDirectly(localStackId);
// Board board = dataBaseAdapter.getBoardByLocalIdDirectly(localBoardId);
// card.setStackId(stack.getLocalId());
// FullCard fullCard = new FullCard();
// fullCard.setCard(card);
// fullCard.setOwner(owner);
// fullCard.setAccountId(accountId);
// new DataPropagationHelper(serverAdapter, dataBaseAdapter).createEntity(new CardPropagationDataProvider(null, board, stack), fullCard, new IResponseCallback<FullCard>(account) {
// @Override
// public void onResponse(FullCard response) {
// liveData.postValue(response);
// }
// }, (FullCard entity, FullCard response) -> {
// response.getCard().setUserId(entity.getCard().getUserId());
// response.getCard().setStackId(stack.getLocalId());
// });
// });
// return liveData;
// }
@AnyThread
public void createFullCard(long accountId, long localBoardId, long localStackId, @NonNull FullCard card, @NonNull IResponseCallback<FullCard> callback) {
executor.submit(() -> {
Account account = dataBaseAdapter.getAccountByIdDirectly(accountId);
User owner = dataBaseAdapter.getUserByUidDirectly(accountId, account.getUserName());
FullStack stack = dataBaseAdapter.getFullStackByLocalIdDirectly(localStackId);
Board board = dataBaseAdapter.getBoardByLocalIdDirectly(localBoardId);
card.getCard().setUserId(owner.getLocalId());
card.getCard().setStackId(stack.getLocalId());
card.getCard().setAccountId(accountId);
card.getCard().setStatusEnum(DBStatus.LOCAL_EDITED);
card.getCard().setOrder(dataBaseAdapter.getHighestCardOrderInStack(localStackId) + 1);
long localCardId = dataBaseAdapter.createCardDirectly(accountId, card.getCard());
card.getCard().setLocalId(localCardId);
List<User> assignedUsers = card.getAssignedUsers();
if (assignedUsers != null) {
for (User assignedUser : assignedUsers) {
dataBaseAdapter.createJoinCardWithUser(assignedUser.getLocalId(), localCardId, DBStatus.LOCAL_EDITED);
}
}
List<Label> labels = card.getLabels();
if (labels != null) {
for (Label label : labels) {
dataBaseAdapter.createJoinCardWithLabel(label.getLocalId(), localCardId, DBStatus.LOCAL_EDITED);
}
}
if (card.getAttachments() != null) {
for (Attachment attachment : card.getAttachments()) {
if (attachment.getLocalId() == null) {
attachment.setCardId(localCardId);
dataBaseAdapter.createAttachment(accountId, attachment);
}
}
}
if (serverAdapter.hasInternetConnection()) {
syncHelperFactory.create(serverAdapter, dataBaseAdapter, null).setResponseCallback(new ResponseCallback<>(account) {
@Override
public void onResponse(Boolean response) {
callback.onResponse(card);
}
@SuppressLint("MissingSuperCall")
@Override
public void onError(Throwable throwable) {
if (throwable.getClass() == DeckException.class && ((DeckException) throwable).getHint().equals(DeckException.Hint.DEPENDENCY_NOT_SYNCED_YET)) {
callback.onResponse(card);
} else {
callback.onError(throwable);
}
}
}).doUpSyncFor(new CardDataProvider(null, board, stack));
} else {
callback.onResponse(card);
}
});
}
use of it.niedermann.nextcloud.deck.api.IResponseCallback in project nextcloud-deck by stefan-niedermann.
the class SyncManager method createAccessControl.
@AnyThread
public void createAccessControl(long accountId, @NonNull AccessControl entity, @NonNull IResponseCallback<AccessControl> callback) {
executor.submit(() -> {
Account account = dataBaseAdapter.getAccountByIdDirectly(accountId);
FullBoard board = dataBaseAdapter.getFullBoardByLocalIdDirectly(accountId, entity.getBoardId());
new DataPropagationHelper(serverAdapter, dataBaseAdapter, executor).createEntity(new AccessControlDataProvider(null, board, Collections.singletonList(entity)), entity, ResponseCallback.from(account, callback), ((entity1, response) -> {
response.setBoardId(entity.getBoardId());
response.setUserId(entity.getUser().getLocalId());
}));
});
}
use of it.niedermann.nextcloud.deck.api.IResponseCallback in project nextcloud-deck by stefan-niedermann.
the class SyncManager method cloneBoard.
/**
* Creates a new {@link Board} and adds the same {@link Label} and {@link Stack} as in the origin {@link Board}.
* Owner of the target {@link Board} will be the {@link User} with the {@link Account} of {@param targetAccountId}.
*
* @param cloneCards determines whether or not the cards in this {@link Board} shall be cloned or not
* Does <strong>not</strong> clone any {@link Card} or {@link AccessControl} from the origin {@link Board}.
*/
@AnyThread
public void cloneBoard(long originAccountId, long originBoardLocalId, long targetAccountId, @ColorInt int targetBoardColor, boolean cloneCards, @NonNull IResponseCallback<FullBoard> callback) {
executor.submit(() -> {
Account originAccount = dataBaseAdapter.getAccountByIdDirectly(originAccountId);
User newOwner = dataBaseAdapter.getUserByUidDirectly(originAccountId, originAccount.getUserName());
if (newOwner == null) {
callback.onError(new DeckException(DeckException.Hint.UNKNOWN_ACCOUNT_USER_ID, "User with Account-UID \"" + originAccount.getUserName() + "\" not found."));
return;
}
FullBoard originalBoard = dataBaseAdapter.getFullBoardByLocalIdDirectly(originAccountId, originBoardLocalId);
String newBoardTitleBaseName = originalBoard.getBoard().getTitle().trim();
int newBoardTitleCopyIndex = 0;
// already a copy?
String regex = " \\(copy [0-9]+\\)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(originalBoard.getBoard().getTitle());
if (matcher.find()) {
String found = matcher.group();
newBoardTitleBaseName = newBoardTitleBaseName.substring(0, newBoardTitleBaseName.length() - found.length());
Matcher indexMatcher = Pattern.compile("[0-9]+").matcher(found);
// noinspection ResultOfMethodCallIgnored
indexMatcher.find();
String oldIndexString = indexMatcher.group();
newBoardTitleCopyIndex = Integer.parseInt(oldIndexString);
}
String newBoardTitle;
do {
newBoardTitleCopyIndex++;
newBoardTitle = newBoardTitleBaseName + " (copy " + newBoardTitleCopyIndex + ")";
} while (dataBaseAdapter.getBoardForAccountByNameDirectly(targetAccountId, newBoardTitle) != null);
originalBoard.setAccountId(targetAccountId);
originalBoard.setId(null);
originalBoard.setLocalId(null);
originalBoard.getBoard().setTitle(newBoardTitle);
originalBoard.getBoard().setColor(String.format("%06X", 0xFFFFFF & targetBoardColor));
originalBoard.getBoard().setOwnerId(newOwner.getLocalId());
originalBoard.setStatusEnum(DBStatus.LOCAL_EDITED);
originalBoard.setOwner(newOwner);
long newBoardId = dataBaseAdapter.createBoardDirectly(originAccountId, originalBoard.getBoard());
originalBoard.setLocalId(newBoardId);
boolean isSameAccount = targetAccountId == originAccountId;
if (isSameAccount) {
List<AccessControl> aclList = originalBoard.getParticipants();
for (AccessControl acl : aclList) {
acl.setLocalId(null);
acl.setId(null);
acl.setBoardId(newBoardId);
dataBaseAdapter.createAccessControl(targetAccountId, acl);
}
}
Map<Long, Long> oldToNewLabelIdsDictionary = new HashMap<>();
for (Label label : originalBoard.getLabels()) {
Long oldLocalId = label.getLocalId();
label.setLocalId(null);
label.setId(null);
label.setAccountId(targetAccountId);
label.setStatusEnum(DBStatus.LOCAL_EDITED);
label.setBoardId(newBoardId);
long newLocalId = dataBaseAdapter.createLabelDirectly(targetAccountId, label);
oldToNewLabelIdsDictionary.put(oldLocalId, newLocalId);
}
List<Stack> oldStacks = originalBoard.getStacks();
for (Stack stack : oldStacks) {
Long oldStackId = stack.getLocalId();
stack.setLocalId(null);
stack.setId(null);
stack.setStatusEnum(DBStatus.LOCAL_EDITED);
stack.setAccountId(targetAccountId);
stack.setBoardId(newBoardId);
long createdStackId = dataBaseAdapter.createStack(targetAccountId, stack);
if (cloneCards) {
List<FullCard> oldCards = dataBaseAdapter.getFullCardsForStackDirectly(originAccountId, oldStackId, null);
for (FullCard oldCard : oldCards) {
Card newCard = oldCard.getCard();
newCard.setId(null);
newCard.setUserId(newOwner.getLocalId());
newCard.setLocalId(null);
newCard.setStackId(createdStackId);
newCard.setAccountId(targetAccountId);
newCard.setStatusEnum(DBStatus.LOCAL_EDITED);
long createdCardId = dataBaseAdapter.createCardDirectly(targetAccountId, newCard);
if (oldCard.getLabels() != null) {
for (Label oldLabel : oldCard.getLabels()) {
Long newLabelId = oldToNewLabelIdsDictionary.get(oldLabel.getLocalId());
if (newLabelId != null) {
dataBaseAdapter.createJoinCardWithLabel(newLabelId, createdCardId, DBStatus.LOCAL_EDITED);
} else
DeckLog.error("ID of created Label is null! Skipping assignment of ", oldLabel.getTitle(), "…");
}
}
if (isSameAccount && oldCard.getAssignedUsers() != null) {
for (User assignedUser : oldCard.getAssignedUsers()) {
dataBaseAdapter.createJoinCardWithUser(assignedUser.getLocalId(), createdCardId, DBStatus.LOCAL_EDITED);
}
}
}
}
}
if (serverAdapter.hasInternetConnection()) {
Account targetAccount = dataBaseAdapter.getAccountByIdDirectly(targetAccountId);
ServerAdapter serverAdapterToUse = this.serverAdapter;
if (originAccountId != targetAccountId) {
serverAdapterToUse = new ServerAdapter(appContext, targetAccount.getName());
}
syncHelperFactory.create(serverAdapterToUse, dataBaseAdapter, null).setResponseCallback(new ResponseCallback<>(targetAccount) {
@Override
public void onResponse(Boolean response) {
callback.onResponse(dataBaseAdapter.getFullBoardByLocalIdDirectly(targetAccountId, newBoardId));
}
@SuppressLint("MissingSuperCall")
@Override
public void onError(Throwable throwable) {
callback.onError(throwable);
}
}).doUpSyncFor(new BoardWithStacksAndLabelsUpSyncDataProvider(dataBaseAdapter.getFullBoardByLocalIdDirectly(targetAccountId, newBoardId)));
} else {
callback.onResponse(dataBaseAdapter.getFullBoardByLocalIdDirectly(targetAccountId, newBoardId));
}
});
}
use of it.niedermann.nextcloud.deck.api.IResponseCallback in project nextcloud-deck by stefan-niedermann.
the class ImportAccountActivity method onActivityResult.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_AUTH_TOKEN_SSO && resultCode == RESULT_CANCELED) {
binding.addButton.setEnabled(true);
} else {
try {
AccountImporter.onActivityResult(requestCode, resultCode, data, ImportAccountActivity.this, new AccountImporter.IAccountAccessGranted() {
@SuppressLint("ApplySharedPref")
@Override
public void accountAccessGranted(SingleSignOnAccount account) {
runOnUiThread(() -> {
binding.status.setText(null);
binding.status.setVisibility(View.GONE);
binding.progressCircular.setVisibility(View.VISIBLE);
binding.progressText.setVisibility(View.VISIBLE);
binding.progressCircular.setIndeterminate(true);
binding.progressText.setText(R.string.progress_import_indeterminate);
});
SingleAccountHelper.setCurrentAccount(getApplicationContext(), account.name);
final var syncManager = new SyncManager(ImportAccountActivity.this);
final var accountToCreate = new Account(account.name, account.userId, account.url);
syncManager.createAccount(accountToCreate, new IResponseCallback<>() {
@Override
public void onResponse(Account createdAccount) {
// Remember last account - THIS HAS TO BE DONE SYNCHRONOUSLY
DeckLog.log("--- Write: shared_preference_last_account | ", createdAccount.getId());
sharedPreferences.edit().putLong(sharedPreferenceLastAccount, createdAccount.getId()).commit();
syncManager.refreshCapabilities(new ResponseCallback<>(createdAccount) {
@Override
public void onResponse(Capabilities response) {
if (!response.isMaintenanceEnabled()) {
if (response.getDeckVersion().isSupported()) {
var progress$ = syncManager.synchronize(new ResponseCallback<>(account) {
@Override
public void onResponse(Boolean response) {
restoreWifiPref();
SyncWorker.update(getApplicationContext());
setResult(RESULT_OK);
finish();
}
@Override
public void onError(Throwable throwable) {
super.onError(throwable);
setStatusText(throwable.getMessage());
runOnUiThread(() -> ExceptionDialogFragment.newInstance(throwable, createdAccount).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()));
rollbackAccountCreation(syncManager, createdAccount.getId());
}
});
runOnUiThread(() -> progress$.observe(ImportAccountActivity.this, (progress) -> {
DeckLog.log("New progress value", progress.first, progress.second);
if (progress.first > 0) {
binding.progressCircular.setIndeterminate(false);
}
binding.progressText.setText(getString(R.string.progress_import, progress.first + 1, progress.second));
binding.progressCircular.setProgress(progress.first);
binding.progressCircular.setMax(progress.second);
}));
} else {
setStatusText(getString(R.string.deck_outdated_please_update, response.getDeckVersion().getOriginalVersion()));
runOnUiThread(() -> {
binding.updateDeckButton.setOnClickListener((v) -> startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(createdAccount.getUrl() + urlFragmentUpdateDeck))));
binding.updateDeckButton.setVisibility(View.VISIBLE);
});
rollbackAccountCreation(syncManager, createdAccount.getId());
}
} else {
setStatusText(R.string.maintenance_mode);
rollbackAccountCreation(syncManager, createdAccount.getId());
}
}
@Override
public void onError(Throwable throwable) {
super.onError(throwable);
if (throwable instanceof OfflineException) {
setStatusText(R.string.you_have_to_be_connected_to_the_internet_in_order_to_add_an_account);
} else {
setStatusText(throwable.getMessage());
runOnUiThread(() -> ExceptionDialogFragment.newInstance(throwable, createdAccount).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()));
}
rollbackAccountCreation(syncManager, createdAccount.getId());
}
});
}
@Override
public void onError(Throwable error) {
IResponseCallback.super.onError(error);
if (error instanceof SQLiteConstraintException) {
DeckLog.error("Account has already been added, this should not be the case");
}
setStatusText(error.getMessage());
runOnUiThread(() -> ExceptionDialogFragment.newInstance(error, accountToCreate).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()));
restoreWifiPref();
}
});
}
});
} catch (AccountImportCancelledException e) {
runOnUiThread(() -> binding.addButton.setEnabled(true));
restoreWifiPref();
DeckLog.info("Account import has been canceled.");
}
}
}
use of it.niedermann.nextcloud.deck.api.IResponseCallback in project nextcloud-deck by stefan-niedermann.
the class SyncManagerTest method testSynchronize.
@Test
public void testSynchronize() {
final var syncManagerSpy = spy(syncManager);
LastSyncUtil.init(ApplicationProvider.getApplicationContext());
final var account = new Account(1337L, "Test", "Peter", "example.com");
final var capabilities = new Capabilities();
capabilities.setDeckVersion(Version.minimumSupported());
// Act as if refreshing capabilities is always successful
doAnswer((invocation -> {
// noinspection unchecked
((IResponseCallback<Capabilities>) invocation.getArgument(0)).onResponse(capabilities);
return null;
})).when(syncManagerSpy).refreshCapabilities(any());
// Actual method invocation
final var finalCallback = spy(new ResponseCallback<Boolean>(account) {
@Override
public void onResponse(Boolean response) {
}
});
// Happy path
final var syncHelper_positive = new SyncHelperMock(true);
when(syncHelperFactory.create(any(), any(), any())).thenReturn(syncHelper_positive);
syncManagerSpy.synchronize(finalCallback);
verify(finalCallback, times(1)).onResponse(any());
// Bad paths
assertThrows(IllegalArgumentException.class, () -> syncManagerSpy.synchronize(new ResponseCallback<>(new Account(null)) {
@Override
public void onResponse(Boolean response) {
}
}));
// noinspection ConstantConditions
assertThrows(IllegalArgumentException.class, () -> syncManagerSpy.synchronize(new ResponseCallback<>(null) {
@Override
public void onResponse(Boolean response) {
}
}));
final var syncHelper_negative = new SyncHelperMock(false);
when(syncHelperFactory.create(any(), any(), any())).thenReturn(syncHelper_negative);
syncManagerSpy.synchronize(finalCallback);
verify(finalCallback, times(1)).onError(any());
}
Aggregations