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