refactoring code

This commit is contained in:
yb 2022-06-30 17:02:44 +02:00
parent 47cf540fc3
commit 97c4102c47
24 changed files with 97 additions and 175 deletions

View File

@ -1,6 +1,7 @@
package eu.csc.vehown.data;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.ui.models.Result;
import java.io.IOException;

View File

@ -1,6 +1,7 @@
package eu.csc.vehown.data;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.ui.models.Result;
/**
* Class that requests authentication and user information from the remote data source and

View File

@ -1,48 +0,0 @@
package eu.csc.vehown.data;
/**
* A generic class that holds a result success w/ data or an error exception.
*/
public class Result<T> {
// hide the private constructor to limit subclass types (Success, Error)
private Result() {
}
@Override
public String toString() {
if (this instanceof Result.Success) {
Result.Success success = (Result.Success) this;
return "Success[data=" + success.getData().toString() + "]";
} else if (this instanceof Result.Error) {
Result.Error error = (Result.Error) this;
return "Error[exception=" + error.getError().toString() + "]";
}
return "";
}
// Success sub-class
public final static class Success<T> extends Result {
private T data;
public Success(T data) {
this.data = data;
}
public T getData() {
return this.data;
}
}
// Error sub-class
public final static class Error extends Result {
private Exception error;
public Error(Exception error) {
this.error = error;
}
public Exception getError() {
return this.error;
}
}
}

View File

@ -12,6 +12,7 @@ import eu.csc.ODPAppVehOwnServer.models.UserRegistrationDto;
import eu.csc.ODPAppVehOwnServer.models.auth.AuthenticationRequest;
import eu.csc.ODPAppVehOwnServer.models.regist.CustomerVehicleDto;
import eu.csc.vehown.data.model.ICustomer;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.data.model.Vehicle;
import eu.csc.vehown.services.rest.vehownserver.pub.OfflineDummyCall;
import lombok.var;
@ -19,6 +20,7 @@ import lombok.var;
import retrofit2.Call;
import java.io.IOException;
import java.util.concurrent.Executor;
public class VehOwnApiClientFactory {
@ -67,7 +69,9 @@ public class VehOwnApiClientFactory {
return s.registerCustomerVehicle(vehicle);
}
public JWTTokenResponse getAccessToken(ICustomer customer) throws IOException {
public static JWTTokenResponse getAccessToken(ICustomer customer) throws IOException {
if (customer == null)
@ -77,7 +81,7 @@ public class VehOwnApiClientFactory {
}
public JWTTokenResponse getAccessToken(String email, String password) throws IOException {
public static JWTTokenResponse getAccessToken(String email, String password) throws IOException {
if (dummyMode) {
@ -129,4 +133,24 @@ public class VehOwnApiClientFactory {
return ClientFactory.createService(getURL(), AuthenticationService.class)
.registerCustomer(dto);
}
public static LoggedInUser fetchUserProfil(String email, String password) throws IOException {
LoggedInUser result = new LoggedInUser();
if(dummyMode)
{
result.setLogin(email);
result.setPassword(password);
}else{
var call = ClientFactory.createAuthenticationService(getURL(), email, password).fetchCustomerProfile();
var response = call.execute();
if(response.isSuccessful())
{
result.setFirstname(response.body().getFirstname());
result.setLastname(response.body().getLastname());
}
}
return result;
}
}

View File

@ -1,9 +1,11 @@
package eu.csc.vehown.ui.fragments.data;
import eu.csc.vehown.ui.fragments.data.model.LoggedInUser;
import java.io.IOException;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.ui.models.Result;
/**
* Class that handles authentication w/ login credentials and retrieves user information.
*/

View File

@ -1,6 +1,8 @@
package eu.csc.vehown.ui.fragments.data;
import eu.csc.vehown.ui.fragments.data.model.LoggedInUser;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.ui.models.Result;
import eu.csc.vehown.ui.registration.data.CustomerContentDataSource;
/**
* Class that requests authentication and user information from the remote data source and
@ -10,18 +12,18 @@ public class LoginRepository {
private static volatile LoginRepository instance;
private LoginDataSource dataSource;
private CustomerContentDataSource dataSource;
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
private LoggedInUser user = null;
// private constructor : singleton access
private LoginRepository(LoginDataSource dataSource) {
private LoginRepository(CustomerContentDataSource dataSource) {
this.dataSource = dataSource;
}
public static LoginRepository getInstance(LoginDataSource dataSource) {
public static LoginRepository getInstance(CustomerContentDataSource dataSource) {
if (instance == null) {
instance = new LoginRepository(dataSource);
}
@ -47,7 +49,7 @@ public class LoginRepository {
// handle login
Result<LoggedInUser> result = dataSource.login(username, password);
if (result instanceof Result.Success) {
setLoggedInUser(((Result.Success<LoggedInUser>) result).getData());
// setLoggedInUser(((Result.Success<LoggedInUser>) result).getData());
}
return result;
}

View File

@ -1,48 +0,0 @@
package eu.csc.vehown.ui.fragments.data;
/**
* A generic class that holds a result success w/ data or an error exception.
*/
public class Result<T> {
// hide the private constructor to limit subclass types (Success, Error)
private Result() {
}
@Override
public String toString() {
if (this instanceof Result.Success) {
Result.Success success = (Result.Success) this;
return "Success[data=" + success.getData().toString() + "]";
} else if (this instanceof Result.Error) {
Result.Error error = (Result.Error) this;
return "Error[exception=" + error.getError().toString() + "]";
}
return "";
}
// Success sub-class
public final static class Success<T> extends Result {
private T data;
public Success(T data) {
this.data = data;
}
public T getData() {
return this.data;
}
}
// Error sub-class
public final static class Error extends Result {
private Exception error;
public Error(Exception error) {
this.error = error;
}
public Exception getError() {
return this.error;
}
}
}

View File

@ -1,23 +0,0 @@
package eu.csc.vehown.ui.fragments.data.model;
/**
* Data class that captures user information for logged in users retrieved from LoginRepository
*/
public class LoggedInUser {
private String userId;
private String displayName;
public LoggedInUser(String userId, String displayName) {
this.userId = userId;
this.displayName = displayName;
}
public String getUserId() {
return userId;
}
public String getDisplayName() {
return displayName;
}
}

View File

@ -23,14 +23,20 @@ import android.widget.TextView;
import android.widget.Toast;
import eu.csc.vehown.R;
import eu.csc.vehown.databinding.FragmentLoginBinding;
import eu.csc.vehown.persist.sharedPreferences.LocalStorageClient;
import eu.csc.vehown.persist.sharedPreferences.SharedPreferencesFactory;
import eu.csc.vehown.ui.models.LoggedInUserView;
import eu.csc.vehown.ui.models.LoginResult;
import eu.csc.vehown.ui.registration.customer.FragmentCustomerRegistrationViewModel;
import eu.csc.vehown.ui.viewmodels.AppViewModelFactory;
public class LoginFragment extends Fragment {
private LoginViewModel loginViewModel;
private FragmentLoginBinding binding;
private LocalStorageClient localStorageClient;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@ -38,6 +44,9 @@ public class LoginFragment extends Fragment {
@Nullable Bundle savedInstanceState) {
binding = FragmentLoginBinding.inflate(inflater, container, false);
localStorageClient = SharedPreferencesFactory.getInstance(getContext());
return binding.getRoot();
}
@ -45,7 +54,7 @@ public class LoginFragment extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
loginViewModel = new ViewModelProvider(this, new LoginViewModelFactory())
loginViewModel = new ViewModelProvider(this, new AppViewModelFactory(getContext()))
.get(LoginViewModel.class);
final EditText usernameEditText = binding.edEmail;

View File

@ -6,11 +6,11 @@ import androidx.lifecycle.ViewModel;
import android.util.Patterns;
import eu.csc.vehown.R;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.ui.fragments.data.LoginRepository;
import eu.csc.vehown.ui.fragments.data.Result;
import eu.csc.vehown.ui.fragments.data.model.LoggedInUser;
import eu.csc.vehown.ui.models.LoggedInUserView;
import eu.csc.vehown.ui.models.LoginResult;
import eu.csc.vehown.ui.models.Result;
public class LoginViewModel extends ViewModel {
@ -18,7 +18,7 @@ public class LoginViewModel extends ViewModel {
private MutableLiveData<LoginResult> loginResult = new MutableLiveData<>();
private LoginRepository loginRepository;
LoginViewModel(LoginRepository loginRepository) {
public LoginViewModel(LoginRepository loginRepository) {
this.loginRepository = loginRepository;
}

View File

@ -1,26 +0,0 @@
package eu.csc.vehown.ui.fragments.ui.login;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.annotation.NonNull;
import eu.csc.vehown.ui.fragments.data.LoginDataSource;
import eu.csc.vehown.ui.fragments.data.LoginRepository;
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
public class LoginViewModelFactory implements ViewModelProvider.Factory {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(LoginViewModel.class)) {
return (T) new LoginViewModel(LoginRepository.getInstance(new LoginDataSource()));
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
}

View File

@ -32,11 +32,12 @@ import eu.csc.vehown.ui.register.RegisterCustomerActivity;
import eu.csc.vehown.ui.registration.customer.FragmentCustomerRegistration;
/**
*
* @see FragmentCustomerRegistration
* @see LoginFragment
*/
public class LoginActivity extends AppCompatActivity {
private Button btnShowRegistration;
private Button btnSwitchView;
private boolean loginVisible;
@ -47,9 +48,9 @@ public class LoginActivity extends AppCompatActivity {
setContentView(R.layout.activity_login);
btnShowRegistration = findViewById(R.id.btnShowRegistration);
btnSwitchView = findViewById(R.id.btnSwitchView);
btnShowRegistration.setOnClickListener(new View.OnClickListener() {
btnSwitchView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchView();
@ -175,7 +176,7 @@ public class LoginActivity extends AppCompatActivity {
fragmentTransaction.commit();
loginVisible = false;
btnShowRegistration.setText("Login");
btnSwitchView.setText("Login");
}
private void showLogin() {
@ -186,7 +187,7 @@ public class LoginActivity extends AppCompatActivity {
fragmentTransaction.commit();
loginVisible = true;
btnShowRegistration.setText("Register");
btnSwitchView.setText("Register");
}
}

View File

@ -39,6 +39,9 @@ import eu.csc.vehown.ui.settings.SettingsActivity;
import eu.csc.vehown.ui.svi.DashboardActivity;
import eu.csc.vehown.ui.svi.RegisterSVIActivity;
/**
* @see LoginActivity
*/
public class MainActivity extends AppCompatActivity {
// private static final int PERMISSIONS_REQUESTED = 1;
@ -125,7 +128,7 @@ public class MainActivity extends AppCompatActivity {
Intent intent = null;
switch (item.getItemId()) {
case R.id.nav_login:
showLogin();
intent = showLogin();
break;
case R.id.nav_list_content:

View File

@ -3,10 +3,10 @@ package eu.csc.vehown.ui.register;
import android.content.Context;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import eu.csc.vehown.data.Result;
import eu.csc.vehown.data.model.*;
import eu.csc.vehown.services.rest.vehownserver.VehOwnApiClientFactory;
import eu.csc.vehown.ui.modal.Helper;
import eu.csc.vehown.ui.models.Result;
import eu.csc.vehown.ui.registration.data.CustomerVehicleRegistrationRepository;
import lombok.Getter;

View File

@ -50,6 +50,24 @@ public class CustomerContentDataSource {
}
public Result<LoggedInUser> login(String email, String password) {
try {
var profile = VehOwnApiClientFactory.fetchUserProfil(email, password);
LoggedInUser fakeUser =
new LoggedInUser(
profile.getEmail(),
profile.getEmail());
return new Result.Success<>(fakeUser);
} catch (IOException ioException) {
ioException.printStackTrace();
return new Result.Error(new Exception("Error logging in ", ioException));
}
}
public Result<LoggedInUser> login(ICustomer customer) {
try {

View File

@ -8,11 +8,6 @@ import androidx.lifecycle.ViewModel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import eu.csc.vehown.data.Result;
import eu.csc.vehown.data.model.Language;
import eu.csc.vehown.data.model.Vehicle;
import eu.csc.vehown.data.model.VehicleBrand;
import eu.csc.vehown.data.model.VehicleModel;
@ -20,6 +15,7 @@ import eu.csc.vehown.data.model.VehiclePropulsionType;
import eu.csc.vehown.persist.sharedPreferences.LocalStorageClient;
import eu.csc.vehown.services.rest.vehownserver.VehOwnApiClientFactory;
import eu.csc.vehown.ui.modal.Helper;
import eu.csc.vehown.ui.models.Result;
import eu.csc.vehown.ui.registration.data.CustomerContentDataSource;
import eu.csc.vehown.ui.registration.data.CustomerRegistrationRepository;
import eu.csc.vehown.ui.registration.data.CustomerVehicleRegistrationRepository;

View File

@ -20,8 +20,8 @@ import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import eu.csc.vehown.R;
import eu.csc.vehown.data.Result;
import eu.csc.vehown.data.model.SVIVehicleModel;
import eu.csc.vehown.ui.models.Result;
import eu.csc.vehown.ui.svi.pairing.PairingViewModel;
import java.io.FileNotFoundException;

View File

@ -19,9 +19,9 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import eu.csc.vehown.R;
import eu.csc.vehown.data.Result;
import eu.csc.vehown.data.model.SVIVehicleModel;
import eu.csc.vehown.ui.modal.Helper;
import eu.csc.vehown.ui.models.Result;
import eu.csc.vehown.ui.reportEvent.ReportEventActivity;
import eu.csc.vehown.ui.svi.pairing.PairingViewModel;

View File

@ -5,8 +5,8 @@ import android.text.Editable;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import eu.csc.vehown.data.Result;
import eu.csc.vehown.data.model.SVIVehicleModel;
import eu.csc.vehown.ui.models.Result;
import lombok.Getter;
@Getter

View File

@ -7,6 +7,8 @@ import androidx.annotation.NonNull;
import eu.csc.vehown.persist.sharedPreferences.LocalStorageClient;
import eu.csc.vehown.persist.sharedPreferences.SharedPreferencesFactory;
import eu.csc.vehown.ui.fragments.data.LoginRepository;
import eu.csc.vehown.ui.fragments.ui.login.LoginViewModel;
import eu.csc.vehown.ui.register.RegistrationViewModel;
import eu.csc.vehown.ui.registration.customer.FragmentCustomerRegistrationViewModel;
import eu.csc.vehown.ui.registration.data.CustomerContentDataSource;
@ -37,6 +39,13 @@ public class AppViewModelFactory implements ViewModelProvider.Factory {
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
LocalStorageClient localStorage = SharedPreferencesFactory.getInstance(context);
if (modelClass.isAssignableFrom(LoginViewModel.class)) {
return (T) new LoginViewModel(LoginRepository.getInstance(new CustomerContentDataSource()));
}
if (modelClass.isAssignableFrom(CustomerRegistrationViewModel.class)) {
return (T) new CustomerRegistrationViewModel(CustomerRegistrationRepository.getInstance(
new CustomerContentDataSource(),

View File

@ -106,7 +106,7 @@
<Button
android:id="@+id/btnShowRegistration"
android:id="@+id/btnSwitchView"
android:enabled="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -114,7 +114,7 @@
android:layout_marginStart="48dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="48dp"
android:text="@string/action_register_customer"
android:text="@string/btn_no_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -182,6 +182,7 @@
<string name="hint_choose_model">Model</string>
<string name="title_propulsion_type">Propulsion Type</string>
<string name="hint_choose_propulsion_type">Propulsion Type</string>
<string name="btn_no_text">NO_TEXT</string>
<!--string-array name="languages">
<item>english</item>

Binary file not shown.

Binary file not shown.