Implement syncing logic (communication with server doesn't work right now)

This commit is contained in:
sebastian 2024-11-10 11:33:45 +01:00
parent 0c5fffb06c
commit ff80db973c
22 changed files with 646 additions and 9 deletions

124
.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@ -5,12 +5,12 @@ plugins {
android {
namespace = "core.notevault"
compileSdk = 34
compileSdk = 35
defaultConfig {
applicationId = "core.notevault"
minSdk = 28
targetSdk = 34
targetSdk = 35
versionCode = 1
versionName = "1.0"
@ -65,4 +65,5 @@ dependencies {
// Optional: Unterstützung für Kotlin Coroutines oder RxJava
implementation("androidx.room:room-ktx:$room_version") // Für Kotlin-Extensions
implementation("androidx.room:room-rxjava3:$room_version") // Für RxJava-Unterstützung
implementation("androidx.work:work-runtime:2.10.0")
}

View File

@ -12,6 +12,8 @@ import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.fragment.NavHostFragment;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import androidx.navigation.NavController;
@ -22,6 +24,7 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import core.notevault.data.*;
import core.notevault.databinding.ActivityMainBinding;
import core.notevault.sync.SyncWorker;
import core.notevault.sync.auth.AuthRepository;
import core.notevault.sync.auth.LoginCallback;
import core.notevault.ui.gallery.GalleryFragment;
@ -35,8 +38,10 @@ import core.notevault.util.NoteSheetsUtil;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity implements MetaDataDialog.OnMetadataListener,
ConcertEditorDialog.OnConcertEditorListener, ConcertSongSelector.OnSongSelectedListener, LoginCallback {
@ -68,6 +73,25 @@ public class MainActivity extends AppCompatActivity implements MetaDataDialog.On
setupLoginButton();
musicDB = MusicDatabase.getDatabase(this);
scheduleSync();
}
public void scheduleSync() {
// Setze eine Uhrzeit für die Synchronisation
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,11);
calendar.set(Calendar.MINUTE, 32);
calendar.set(Calendar.SECOND, 0);
long triggerTime = calendar.getTimeInMillis(); // Zeitstempel für den Trigger
// Erstelle die OneTimeWorkRequest für den SyncWorker
OneTimeWorkRequest syncRequest = new OneTimeWorkRequest.Builder(SyncWorker.class)
.setInitialDelay(triggerTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS) // Verzögerung bis zur Ausführung
.build();
// Planen des Workers mit WorkManager
WorkManager.getInstance(getBaseContext()).enqueue(syncRequest);
}
@Override

View File

@ -1,26 +1,33 @@
package core.notevault.data;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import androidx.room.*;
import core.notevault.data.sync.SyncStatus;
import core.notevault.data.sync.SyncStatusConverter;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Locale;
@Entity(tableName = "concerts")
@TypeConverters(SyncStatusConverter.class)
public class Concert {
@PrimaryKey(autoGenerate = true)
private int id;
private String serverSpecificConcertID;
private String title;
private String concertDate;
private SyncStatus syncStatus;
private LocalDateTime lastModified;
@Ignore
public Concert(String title, String concertDate) {
this.title = title;
this.concertDate = concertDate;
this.lastModified = LocalDateTime.now();
}
public Concert() {
@ -56,4 +63,28 @@ public class Concert {
public void setConcertDate(String concertDate) {
this.concertDate = concertDate;
}
public String getServerSpecificConcertID() {
return serverSpecificConcertID;
}
public void setServerSpecificConcertID(String serverSpecificConcertID) {
this.serverSpecificConcertID = serverSpecificConcertID;
}
public SyncStatus getSyncStatus() {
return syncStatus;
}
public void setSyncStatus(SyncStatus syncStatus) {
this.syncStatus = syncStatus;
}
public LocalDateTime getLastModified() {
return lastModified;
}
public void setLastModified(LocalDateTime lastModified) {
this.lastModified = lastModified;
}
}

View File

@ -0,0 +1,20 @@
package core.notevault.data;
import androidx.room.TypeConverter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateConverter {
// Konvertiere LocalDateTime in String
@TypeConverter
public static String fromLocalDateTime(LocalDateTime localDateTime) {
return localDateTime == null ? null : localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
// Konvertiere String zurück in LocalDateTime
@TypeConverter
public static LocalDateTime toLocalDateTime(String dateTimeString) {
return dateTimeString == null ? null : LocalDateTime.parse(dateTimeString, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
}

View File

@ -1,11 +1,12 @@
package core.notevault.data;
import android.content.Context;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.Database;
import androidx.room.*;
import core.notevault.data.sync.SyncResponse;
import core.notevault.data.sync.SyncStatusConverter;
@Database(entities = {MusicNote.class, NoteSheet.class, Concert.class, ConcertSong.class}, version = 2, exportSchema = false)
@Database(entities = {MusicNote.class, NoteSheet.class, Concert.class, ConcertSong.class, SyncResponse.class}, version = 2, exportSchema = false)
@TypeConverters(DateConverter.class)
public abstract class MusicDatabase extends RoomDatabase {
public abstract MusicNoteDAO musicNoteDao();

View File

@ -1,7 +1,10 @@
package core.notevault.data;
import androidx.room.*;
import core.notevault.data.sync.SyncResponse;
import core.notevault.data.sync.SyncStatus;
import java.time.LocalDateTime;
import java.util.List;
@Dao
@ -19,6 +22,9 @@ public interface MusicNoteDAO {
@Query("SELECT * FROM note_sheets WHERE musicNoteId = :musicNoteId")
List<NoteSheet> getNoteSheetsForMusicSong(long musicNoteId);
@Query("SELECT * FROM concerts WHERE syncStatus = :status")
List<Concert> getConcertsWithSyncStatus(SyncStatus status);
@Insert
void insertConcert(Concert concert);
@ -43,5 +49,18 @@ public interface MusicNoteDAO {
@Query("DELETE FROM concert_songs WHERE concertID = :concertID AND musicNoteID = :songID")
void deleteConcertSong(long songID, int concertID);
@Query("UPDATE concerts SET serverSpecificConcertID = :serverUUID WHERE id = :concertID")
@Transaction
void updateConcertServerUUID(String serverUUID, int concertID);
// Methode für das batchweise Update der Konzert-ServerUUIDs
@Query("DELETE FROM concerts WHERE serverSpecificConcertID IN (:serverSpecificIDs)")
void deleteConcerts(List<String> serverSpecificIDs);
@Insert
@Transaction
void insertSyncResponses(List<SyncResponse> syncResponses);
@Query("SELECT MAX(lastModified) FROM concerts")
LocalDateTime getLatestSyncTimestamp();
}

View File

@ -0,0 +1,6 @@
package core.notevault.data.sync;
public enum SyncAction {
TOBEUPLOADED,
TOBEDOWNLOADED
}

View File

@ -0,0 +1,15 @@
package core.notevault.data.sync;
import androidx.room.TypeConverter;
public class SyncActionConverter {
@TypeConverter
public static SyncAction fromInt(int value) {
return SyncAction.values()[value];
}
@TypeConverter
public static int toInt(SyncAction action) {
return action.ordinal();
}
}

View File

@ -0,0 +1,5 @@
package core.notevault.data.sync;
public enum SyncObject {
CONCERT
}

View File

@ -0,0 +1,15 @@
package core.notevault.data.sync;
import androidx.room.TypeConverter;
public class SyncObjectConverter {
@TypeConverter
public static SyncObject fromInt(int value) {
return SyncObject.values()[value];
}
@TypeConverter
public static int toInt(SyncObject object) {
return object.ordinal();
}
}

View File

@ -0,0 +1,59 @@
package core.notevault.data.sync;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
@Entity(tableName = "sync_actions")
@TypeConverters({SyncStatusConverter.class, SyncObjectConverter.class})
public class SyncResponse {
@PrimaryKey(autoGenerate = true)
private long id;
private String serverUUID;
private SyncAction syncAction;
private SyncObject syncObject;
@Ignore
public SyncResponse(String serverUUID, SyncAction syncAction, SyncObject syncObject) {
this.serverUUID = serverUUID;
this.syncAction = syncAction;
this.syncObject = syncObject;
}
public SyncResponse() {
}
public String getServerUUID() {
return serverUUID;
}
public void setServerUUID(String serverUUID) {
this.serverUUID = serverUUID;
}
public SyncAction getSyncAction() {
return syncAction;
}
public void setSyncAction(SyncAction syncAction) {
this.syncAction = syncAction;
}
public SyncObject getSyncObject() {
return syncObject;
}
public void setSyncObject(SyncObject syncObject) {
this.syncObject = syncObject;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}

View File

@ -0,0 +1,9 @@
package core.notevault.data.sync;
public enum SyncStatus {
CREATED,
DELETED,
MODIFIED,
REMOTE_MODIFIED,
SYNCED;
}

View File

@ -0,0 +1,15 @@
package core.notevault.data.sync;
import androidx.room.TypeConverter;
public class SyncStatusConverter {
@TypeConverter
public static SyncStatus fromInt(int value) {
return SyncStatus.values()[value];
}
@TypeConverter
public static int toInt(SyncStatus syncStatus) {
return syncStatus.ordinal();
}
}

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import core.notevault.sync.auth.AuthInterceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@ -12,9 +13,13 @@ public class ApiClient {
public static Retrofit getRetrofitInstance(Context context) {
if (retrofit == null) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
SharedPreferences sharedPreferences = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new AuthInterceptor(sharedPreferences))
.addInterceptor(loggingInterceptor)
.build();
retrofit = new Retrofit.Builder()

View File

@ -0,0 +1,127 @@
package core.notevault.sync;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import core.notevault.data.Concert;
import core.notevault.data.MusicDatabase;
import core.notevault.data.MusicNoteDAO;
import core.notevault.data.sync.SyncAction;
import core.notevault.data.sync.SyncObject;
import core.notevault.data.sync.SyncResponse;
import core.notevault.data.sync.SyncStatus;
import core.notevault.sync.synchronisation.*;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
public class SyncWorker extends Worker{
private SyncService syncService;
private MusicNoteDAO database;
public SyncWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.syncService = ApiClient.getRetrofitInstance(context).create(SyncService.class);
MusicDatabase musicDatabase = MusicDatabase.getDatabase(context);
database = musicDatabase.musicNoteDao();
}
@NonNull
@Override
public Result doWork() {
SyncRequest concertSync = buildConcertSyncRequest();
final CountDownLatch latch = new CountDownLatch(1);
final Result[] result = {Result.failure()};
syncWithServer(concertSync, new Callback<SyncResponseModel>() {
@Override
public void onResponse(Call<SyncResponseModel> call, Response<SyncResponseModel> response) {
if(response.isSuccessful()) {
result[0] = Result.success();
Log.d("SyncWorker", "Sync finished, process now");
processConcertSynResponse(response.body());
} else {
Log.d("SyncWorker", "Sync failed");
if (response.errorBody() != null) {
try {
String errorBody = response.errorBody().string();
Log.d("SyncWorker", "Error Body: " + errorBody);
} catch (IOException e) {
e.printStackTrace();
}
}
result[0] = Result.failure();
}
latch.countDown();
}
@Override
public void onFailure(Call<SyncResponseModel> call, Throwable throwable) {
result[0] = Result.failure();
Log.d("SyncWorker", "Sync failure");
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
// throw new RuntimeException(e);
}
return result[0];
}
private SyncRequest buildConcertSyncRequest() {
List<Concert> createdConcerts = database.getConcertsWithSyncStatus(SyncStatus.CREATED);
List<Concert> deletedConcerts = database.getConcertsWithSyncStatus(SyncStatus.DELETED);
List<Concert> modifiedConcerts = database.getConcertsWithSyncStatus(SyncStatus.MODIFIED);
List<Integer> deviceIDsCreatedConcerts = createdConcerts.stream().map(Concert::getId).collect(Collectors.toList());
List<SyncChangeRequest> modifiedSyncRequests = modifiedConcerts.stream().map(concert ->
new SyncChangeRequest(concert.getServerSpecificConcertID(), concert.getLastModified())).collect(Collectors.toList());
List<SyncChangeRequest> deletedSyncRequests = deletedConcerts.stream().map(concert ->
new SyncChangeRequest(concert.getServerSpecificConcertID(), concert.getLastModified())).collect(Collectors.toList());
Log.d("SyncWorker", "Build SyncRequest");
// Datenbankabfrage: Nur IDs mit Zustand "Modified" oder "Deleted" abrufen
// Dies ist abhängig von der spezifischen Implementierung der Datenbank
return new SyncRequest(database.getLatestSyncTimestamp(), deletedSyncRequests, modifiedSyncRequests, deviceIDsCreatedConcerts);
}
private void syncWithServer(SyncRequest syncRequest, Callback<SyncResponseModel> callback) {
syncService.syncConcerts(syncRequest).enqueue(callback);
}
private void processConcertSynResponse(SyncResponseModel syncResponse) {
Log.d("SyncWorker", "Process SyncResponse");
//Assign local Concert entries the provided Server ID
List<SyncResponse> syncResponses = new ArrayList<>();
for(SyncCreateResponse createResponse : syncResponse.getCreateResonses()) {
database.updateConcertServerUUID(createResponse.getServerObjectUUID(), createResponse.getDeviceSpecificObjectID());
syncResponses.add(new SyncResponse(createResponse.getServerObjectUUID(), SyncAction.TOBEUPLOADED, SyncObject.CONCERT));
}
//Delete Concerts that the server has marked as deleted
database.deleteConcerts(syncResponse.getToBeDeleted());
//Persist SyncResponse
for(String toBeDownloaded : syncResponse.getToBeDownloaded()) {
syncResponses.add(new SyncResponse(toBeDownloaded, SyncAction.TOBEDOWNLOADED, SyncObject.CONCERT));
}
for(String toBeUploaded : syncResponse.getToBeUploaded()) {
syncResponses.add(new SyncResponse(toBeUploaded, SyncAction.TOBEUPLOADED, SyncObject.CONCERT));
}
database.insertSyncResponses(syncResponses);
}
}

View File

@ -1,6 +1,7 @@
package core.notevault.sync.auth;
import android.content.SharedPreferences;
import android.util.Log;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
@ -13,12 +14,17 @@ public class AuthInterceptor implements Interceptor {
public AuthInterceptor(SharedPreferences sharedPreferences) {
this.sharedPreferences = sharedPreferences;
String token = sharedPreferences.getString("jwt_token", null);
}
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if(originalRequest.url().encodedPath().equals("/api/v1/auth/login")) {
return chain.proceed(originalRequest);
}
String token = sharedPreferences.getString("jwt_token", null);
if (token == null) {
return chain.proceed(originalRequest);

View File

@ -0,0 +1,29 @@
package core.notevault.sync.synchronisation;
import java.time.LocalDateTime;
public class SyncChangeRequest {
private String serverUUID;
private LocalDateTime lastModified;
public SyncChangeRequest(String serverUUID, LocalDateTime lastModified) {
this.serverUUID = serverUUID;
this.lastModified = lastModified;
}
public String getServerUUID() {
return serverUUID;
}
public void setServerUUID(String serverUUID) {
this.serverUUID = serverUUID;
}
public LocalDateTime getLastModified() {
return lastModified;
}
public void setLastModified(LocalDateTime lastModified) {
this.lastModified = lastModified;
}
}

View File

@ -0,0 +1,22 @@
package core.notevault.sync.synchronisation;
public class SyncCreateResponse {
private String serverObjectUUID;
private int deviceSpecificObjectID;
public String getServerObjectUUID() {
return serverObjectUUID;
}
public void setServerObjectUUID(String serverObjectUUID) {
this.serverObjectUUID = serverObjectUUID;
}
public int getDeviceSpecificObjectID() {
return deviceSpecificObjectID;
}
public void setDeviceSpecificObjectID(int deviceSpecificObjectID) {
this.deviceSpecificObjectID = deviceSpecificObjectID;
}
}

View File

@ -0,0 +1,50 @@
package core.notevault.sync.synchronisation;
import java.time.LocalDateTime;
import java.util.List;
public class SyncRequest {
private LocalDateTime lastSync;
private List<SyncChangeRequest> deletedConcerts;
private List<SyncChangeRequest> modifiedConcerts;
private List<Integer> createdConcerts;
public SyncRequest(LocalDateTime lastSync, List<SyncChangeRequest> deletedConcerts, List<SyncChangeRequest> modifiedConcerts, List<Integer> createdConcerts) {
this.lastSync = lastSync;
this.deletedConcerts = deletedConcerts;
this.modifiedConcerts = modifiedConcerts;
this.createdConcerts = createdConcerts;
}
public LocalDateTime getLastSync() {
return lastSync;
}
public void setLastSync(LocalDateTime lastSync) {
this.lastSync = lastSync;
}
public List<SyncChangeRequest> getDeletedConcerts() {
return deletedConcerts;
}
public void setDeletedConcerts(List<SyncChangeRequest> deletedConcerts) {
this.deletedConcerts = deletedConcerts;
}
public List<SyncChangeRequest> getModifiedConcerts() {
return modifiedConcerts;
}
public void setModifiedConcerts(List<SyncChangeRequest> modifiedConcerts) {
this.modifiedConcerts = modifiedConcerts;
}
public List<Integer> getCreatedConcerts() {
return createdConcerts;
}
public void setCreatedConcerts(List<Integer> createdConcerts) {
this.createdConcerts = createdConcerts;
}
}

View File

@ -0,0 +1,42 @@
package core.notevault.sync.synchronisation;
import java.util.List;
public class SyncResponseModel {
private List<String> toBeUploaded;
private List<String> toBeDownloaded;
private List<String> toBeDeleted;
private List<SyncCreateResponse> createResonses;
public List<String> getToBeUploaded() {
return toBeUploaded;
}
public void setToBeUploaded(List<String> toBeUploaded) {
this.toBeUploaded = toBeUploaded;
}
public List<String> getToBeDownloaded() {
return toBeDownloaded;
}
public void setToBeDownloaded(List<String> toBeDownloaded) {
this.toBeDownloaded = toBeDownloaded;
}
public List<String> getToBeDeleted() {
return toBeDeleted;
}
public void setToBeDeleted(List<String> toBeDeleted) {
this.toBeDeleted = toBeDeleted;
}
public List<SyncCreateResponse> getCreateResonses() {
return createResonses;
}
public void setCreateResonses(List<SyncCreateResponse> createResonses) {
this.createResonses = createResonses;
}
}

View File

@ -0,0 +1,12 @@
package core.notevault.sync.synchronisation;
import core.notevault.data.sync.SyncResponse;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface SyncService {
@POST("api/v1/sync/concerts")
Call<SyncResponseModel> syncConcerts(@Body SyncRequest syncRequest);
}