parent
d56e41699c
commit
8ce7134a04
@ -1,30 +0,0 @@ |
||||
package com.community.pocket.data.login; |
||||
|
||||
import com.community.pocket.data.model.LoggedInUser; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* Class that handles authentication w/ login credentials and retrieves user information. |
||||
* 该类处理身份验证w/登录凭据并检索用户信息。 |
||||
*/ |
||||
public class LoginDataSource { |
||||
|
||||
public Result<LoggedInUser> login(String username, String password) { |
||||
|
||||
try { |
||||
// TODO: handle loggedInUser authentication
|
||||
LoggedInUser fakeUser = |
||||
new LoggedInUser( |
||||
java.util.UUID.randomUUID().toString(), |
||||
"Jane Doe"); |
||||
return new Result.Success<>(fakeUser); |
||||
} catch (Exception e) { |
||||
return new Result.Error<>(new IOException("Error logging in", e), LoggedInUser.class); |
||||
} |
||||
} |
||||
|
||||
void logout() { |
||||
// TODO: revoke authentication
|
||||
} |
||||
} |
@ -1,56 +0,0 @@ |
||||
package com.community.pocket.data.login; |
||||
|
||||
import com.community.pocket.data.model.LoggedInUser; |
||||
|
||||
/** |
||||
* Class that requests authentication and user information from the remote data source and |
||||
* maintains an in-memory cache of login status and user credentials information. |
||||
* 该类请求来自远程数据源的身份验证和用户信息 |
||||
* 在内存中保存登录状态和用户凭证信息。 |
||||
*/ |
||||
public class LoginRepository { |
||||
|
||||
private static volatile LoginRepository instance; |
||||
|
||||
private LoginDataSource 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) { |
||||
this.dataSource = dataSource; |
||||
} |
||||
|
||||
public static LoginRepository getInstance(LoginDataSource dataSource) { |
||||
if (instance == null) { |
||||
instance = new LoginRepository(dataSource); |
||||
} |
||||
return instance; |
||||
} |
||||
|
||||
public boolean isLoggedIn() { |
||||
return user != null; |
||||
} |
||||
|
||||
public void logout() { |
||||
user = null; |
||||
dataSource.logout(); |
||||
} |
||||
|
||||
private void setLoggedInUser(LoggedInUser user) { |
||||
this.user = user; |
||||
// If user credentials will be cached in local storage, it is recommended it be encrypted
|
||||
// @see https://developer.android.com/training/articles/keystore
|
||||
} |
||||
|
||||
public Result<LoggedInUser> login(String username, String password) { |
||||
// handle login
|
||||
Result<LoggedInUser> result = dataSource.login(username, password); |
||||
if (result instanceof Result.Success) { |
||||
setLoggedInUser(((Result.Success<LoggedInUser>) result).getData()); |
||||
} |
||||
return result; |
||||
} |
||||
} |
@ -0,0 +1,35 @@ |
||||
package com.community.pocket.data.login; |
||||
|
||||
|
||||
import com.community.pocket.R; |
||||
import com.community.pocket.data.model.Token; |
||||
import com.community.pocket.ui.login.LoginResponse; |
||||
|
||||
/** |
||||
* 登陆请求接口 |
||||
* TODO 完善逻辑 |
||||
*/ |
||||
public class LoginRequest { |
||||
private static volatile LoginRequest instance; |
||||
|
||||
private LoginRequest() { |
||||
} |
||||
|
||||
public static LoginRequest getInstance() { |
||||
if (instance == null) { |
||||
instance = new LoginRequest(); |
||||
} |
||||
return instance; |
||||
} |
||||
|
||||
public LoginResponse login(String username, String password) { |
||||
Token token = new Token(); |
||||
token.setTime(System.currentTimeMillis()); |
||||
token.setToken("123"); |
||||
|
||||
LoginResponse loginResponse = new LoginResponse(); |
||||
loginResponse.setSuccess(R.string.login_ok, username); |
||||
loginResponse.setBody(token); |
||||
return loginResponse; |
||||
} |
||||
} |
@ -1,58 +0,0 @@ |
||||
package com.community.pocket.data.login; |
||||
|
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
/** |
||||
* A generic class that holds a result success w/ data or an error exception. |
||||
* 一个泛型类,它持有一个结果成功w/数据或一个错误异常。 |
||||
*/ |
||||
public class Result<T> { |
||||
// hide the private constructor to limit subclass types (Success, Error)
|
||||
private Result() { |
||||
} |
||||
|
||||
@NotNull |
||||
@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<T> { |
||||
private T data; |
||||
|
||||
Success(T data) { |
||||
this.data = data; |
||||
} |
||||
|
||||
public T getData() { |
||||
return this.data; |
||||
} |
||||
} |
||||
|
||||
// Error sub-class
|
||||
final static class Error<T> extends Result<T> { |
||||
private Exception error; |
||||
private Class<T> c; |
||||
|
||||
Error(Exception error, Class<T> c) { |
||||
this.error = error; |
||||
this.c = c; |
||||
} |
||||
|
||||
Exception getError() { |
||||
return this.error; |
||||
} |
||||
|
||||
public Class<T> getC() { |
||||
return c; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
package com.community.pocket.data.model; |
||||
|
||||
/** |
||||
* 登陆令牌 |
||||
*/ |
||||
public class Token { |
||||
private String token; |
||||
|
||||
private long time; |
||||
|
||||
public String getToken() { |
||||
return token; |
||||
} |
||||
|
||||
public void setToken(String token) { |
||||
this.token = token; |
||||
} |
||||
|
||||
public long getTime() { |
||||
return time; |
||||
} |
||||
|
||||
public void setTime(long time) { |
||||
this.time = time; |
||||
} |
||||
} |
@ -0,0 +1,11 @@ |
||||
package com.community.pocket.ui.login; |
||||
|
||||
import com.community.pocket.data.model.Token; |
||||
import com.community.pocket.ui.main.ui.share.Response; |
||||
|
||||
/** |
||||
* 登陆响应结果 |
||||
*/ |
||||
public class LoginResponse extends Response<Token> { |
||||
|
||||
} |
@ -1,32 +0,0 @@ |
||||
package com.community.pocket.ui.login; |
||||
|
||||
import androidx.annotation.Nullable; |
||||
|
||||
/** |
||||
* Authentication result : success (user details) or error message. |
||||
* 验证结果:成功(用户详细信息)或错误消息。 |
||||
*/ |
||||
class LoginResult { |
||||
@Nullable |
||||
private LoggedInUserView success; |
||||
@Nullable |
||||
private Integer error; |
||||
|
||||
LoginResult(@Nullable Integer error) { |
||||
this.error = error; |
||||
} |
||||
|
||||
LoginResult(@Nullable LoggedInUserView success) { |
||||
this.success = success; |
||||
} |
||||
|
||||
@Nullable |
||||
LoggedInUserView getSuccess() { |
||||
return success; |
||||
} |
||||
|
||||
@Nullable |
||||
Integer getError() { |
||||
return error; |
||||
} |
||||
} |
@ -1,28 +0,0 @@ |
||||
package com.community.pocket.ui.login; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.lifecycle.ViewModel; |
||||
import androidx.lifecycle.ViewModelProvider; |
||||
|
||||
import com.community.pocket.data.login.LoginDataSource; |
||||
import com.community.pocket.data.login.LoginRepository; |
||||
|
||||
/** |
||||
* ViewModel provider factory to instantiate LoginViewModel. |
||||
* Required given LoginViewModel has a non-empty constructor |
||||
* ViewModel提供程序工厂来实例化LoginViewModel。 |
||||
* 给定的LoginViewModel有一个非空的构造函数 |
||||
*/ |
||||
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"); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue