KEYCLOAK-19481 Make Id and RealmId mutable fields
This commit is contained in:
parent
26a2bbac60
commit
6e591305f9
21 changed files with 156 additions and 112 deletions
|
@ -38,14 +38,9 @@ public class MapRootAuthenticationSessionEntity implements AbstractEntity, Updat
|
|||
private int timestamp;
|
||||
private Map<String, MapAuthenticationSessionEntity> authenticationSessions = new ConcurrentHashMap<>();
|
||||
|
||||
protected MapRootAuthenticationSessionEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
protected MapRootAuthenticationSessionEntity() {}
|
||||
|
||||
public MapRootAuthenticationSessionEntity(String id, String realmId) {
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
@ -55,6 +50,13 @@ public class MapRootAuthenticationSessionEntity implements AbstractEntity, Updat
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
|
|
@ -109,7 +109,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore {
|
|||
+ ", Resource: " + resourceId + ", owner: " + owner + ", scopeId: " + scopeId + " already exists.");
|
||||
}
|
||||
|
||||
MapPermissionTicketEntity entity = new MapPermissionTicketEntity(null);
|
||||
MapPermissionTicketEntity entity = new MapPermissionTicketEntity();
|
||||
entity.setResourceId(resourceId);
|
||||
entity.setRequester(requester);
|
||||
entity.setCreatedTimestamp(System.currentTimeMillis());
|
||||
|
|
|
@ -24,7 +24,7 @@ import java.util.Objects;
|
|||
|
||||
public class MapPermissionTicketEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private final String id;
|
||||
private String id;
|
||||
private String owner;
|
||||
private String requester;
|
||||
private Long createdTimestamp;
|
||||
|
@ -39,15 +39,20 @@ public class MapPermissionTicketEntity implements AbstractEntity, UpdatableEntit
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public MapPermissionTicketEntity() {
|
||||
this.id = null;
|
||||
}
|
||||
public MapPermissionTicketEntity() {}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.Objects;
|
|||
|
||||
public class MapPolicyEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private final String id;
|
||||
private String id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String type;
|
||||
|
@ -48,9 +48,7 @@ public class MapPolicyEntity implements AbstractEntity, UpdatableEntity {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public MapPolicyEntity() {
|
||||
this.id = null;
|
||||
}
|
||||
public MapPolicyEntity() {}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
|
@ -182,6 +180,13 @@ public class MapPolicyEntity implements AbstractEntity, UpdatableEntity {
|
|||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return updated;
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.util.Set;
|
|||
|
||||
public class MapResourceEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private final String id;
|
||||
private String id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
private final Set<String> uris = new HashSet<>();
|
||||
|
@ -47,15 +47,20 @@ public class MapResourceEntity implements AbstractEntity, UpdatableEntity {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public MapResourceEntity() {
|
||||
this.id = null;
|
||||
}
|
||||
public MapResourceEntity() {}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.util.Objects;
|
|||
|
||||
public class MapResourceServerEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private final String id;
|
||||
private String id;
|
||||
private boolean updated = false;
|
||||
|
||||
private boolean allowRemoteResourceManagement;
|
||||
|
@ -37,15 +37,20 @@ public class MapResourceServerEntity implements AbstractEntity, UpdatableEntity
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public MapResourceServerEntity() {
|
||||
this.id = null;
|
||||
}
|
||||
public MapResourceServerEntity() {}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
public boolean isAllowRemoteResourceManagement() {
|
||||
return allowRemoteResourceManagement;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import java.util.Objects;
|
|||
|
||||
public class MapScopeEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private final String id;
|
||||
private String id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
private String iconUri;
|
||||
|
@ -35,15 +35,20 @@ public class MapScopeEntity implements AbstractEntity, UpdatableEntity {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public MapScopeEntity() {
|
||||
this.id = null;
|
||||
}
|
||||
public MapScopeEntity() {}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -41,10 +41,8 @@ public interface MapClientEntity extends AbstractEntity, UpdatableEntity {
|
|||
*/
|
||||
protected boolean updated;
|
||||
private String id;
|
||||
|
||||
protected AbstractClientEntity() {
|
||||
this.id = null;
|
||||
}
|
||||
|
||||
protected AbstractClientEntity() {}
|
||||
|
||||
public AbstractClientEntity(String id) {
|
||||
this.id = id;
|
||||
|
@ -55,6 +53,13 @@ public interface MapClientEntity extends AbstractEntity, UpdatableEntity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
|
|
@ -468,6 +468,11 @@ public class MapClientEntityLazyDelegate implements MapClientEntity {
|
|||
return getReadDelegate().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
getWriteDelegate().setId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return isWriteDelegateInitialized() && getWriteDelegate().isUpdated();
|
||||
|
|
|
@ -33,8 +33,8 @@ import org.keycloak.models.map.common.UpdatableEntity;
|
|||
|
||||
public class MapClientScopeEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private final String id;
|
||||
private final String realmId;
|
||||
private String id;
|
||||
private String realmId;
|
||||
|
||||
private String name;
|
||||
private String protocol;
|
||||
|
@ -49,14 +49,9 @@ public class MapClientScopeEntity implements AbstractEntity, UpdatableEntity {
|
|||
*/
|
||||
protected boolean updated;
|
||||
|
||||
protected MapClientScopeEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
protected MapClientScopeEntity() {}
|
||||
|
||||
public MapClientScopeEntity(String id, String realmId) {
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
@ -66,6 +61,13 @@ public class MapClientScopeEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
@ -148,6 +150,11 @@ public class MapClientScopeEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.realmId;
|
||||
}
|
||||
|
||||
public void setRealmId(String realmId) {
|
||||
this.updated |= !Objects.equals(this.realmId, realmId);
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
||||
public Stream<String> getScopeMappings() {
|
||||
return scopeMappings.stream();
|
||||
}
|
||||
|
|
|
@ -23,5 +23,5 @@ package org.keycloak.models.map.common;
|
|||
public interface AbstractEntity {
|
||||
|
||||
String getId();
|
||||
|
||||
void setId(String id);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ public class Serialization {
|
|||
.setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
|
||||
.activateDefaultTyping(new LaissezFaireSubTypeValidator() /* TODO - see javadoc */, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT, JsonTypeInfo.As.PROPERTY)
|
||||
.addMixIn(UpdatableEntity.class, IgnoreUpdatedMixIn.class)
|
||||
.addMixIn(AbstractEntity.class, AbstractEntityMixIn.class)
|
||||
;
|
||||
|
||||
public static final ConcurrentHashMap<Class<?>, ObjectReader> READERS = new ConcurrentHashMap<>();
|
||||
|
@ -64,11 +63,6 @@ public class Serialization {
|
|||
@JsonIgnore public abstract boolean isUpdated();
|
||||
}
|
||||
|
||||
abstract class AbstractEntityMixIn {
|
||||
@JsonTypeInfo(property="id", use=Id.CLASS, include=As.WRAPPER_ARRAY)
|
||||
abstract Object getId();
|
||||
}
|
||||
|
||||
static {
|
||||
JavaType type = TypeFactory.unknownType();
|
||||
JavaType streamType = MAPPER.getTypeFactory().constructParametricType(Stream.class, type);
|
||||
|
@ -78,10 +72,6 @@ public class Serialization {
|
|||
|
||||
|
||||
public static <T extends AbstractEntity> T from(T orig) {
|
||||
return from(orig, null);
|
||||
}
|
||||
|
||||
public static <T extends AbstractEntity> T from(T orig, String newId) {
|
||||
if (orig == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -94,26 +84,10 @@ public class Serialization {
|
|||
ObjectWriter writer = WRITERS.computeIfAbsent(origClass, MAPPER::writerFor);
|
||||
final T res;
|
||||
res = reader.readValue(writer.writeValueAsBytes(orig));
|
||||
if (newId != null) {
|
||||
updateId(origClass, res, newId);
|
||||
}
|
||||
|
||||
return res;
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static <K> void updateId(Class<?> origClass, AbstractEntity res, K newId) {
|
||||
Field field = Reflections.findDeclaredField(origClass, "id");
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("Cannot find id for " + origClass + " class");
|
||||
}
|
||||
try {
|
||||
Reflections.setAccessible(field).set(res, newId);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new IllegalArgumentException("Cannot set id for " + origClass + " class");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.Set;
|
|||
public class MapGroupEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private String id;
|
||||
private final String realmId;
|
||||
private String realmId;
|
||||
|
||||
private String name;
|
||||
private String parentId;
|
||||
|
@ -46,14 +46,9 @@ public class MapGroupEntity implements AbstractEntity, UpdatableEntity {
|
|||
*/
|
||||
protected boolean updated;
|
||||
|
||||
protected MapGroupEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
protected MapGroupEntity() {}
|
||||
|
||||
public MapGroupEntity(String id, String realmId) {
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
@ -63,6 +58,13 @@ public class MapGroupEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
@ -113,6 +115,11 @@ public class MapGroupEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.realmId;
|
||||
}
|
||||
|
||||
public void setRealmId(String realmId) {
|
||||
this.updated |= !Objects.equals(this.realmId, realmId);
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
||||
public Set<String> getGrantedRoles() {
|
||||
return grantedRoles;
|
||||
}
|
||||
|
|
|
@ -39,11 +39,7 @@ public class MapUserLoginFailureEntity implements AbstractEntity, UpdatableEntit
|
|||
private long lastFailure;
|
||||
private String lastIPFailure;
|
||||
|
||||
public MapUserLoginFailureEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
this.userId = null;
|
||||
}
|
||||
public MapUserLoginFailureEntity() {}
|
||||
|
||||
public MapUserLoginFailureEntity(String id, String realmId, String userId) {
|
||||
this.id = id;
|
||||
|
@ -56,6 +52,13 @@ public class MapUserLoginFailureEntity implements AbstractEntity, UpdatableEntit
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
|
|
@ -130,9 +130,7 @@ public class MapRealmEntity implements AbstractEntity, UpdatableEntity {
|
|||
*/
|
||||
protected boolean updated;
|
||||
|
||||
protected MapRealmEntity() {
|
||||
this.id = null;
|
||||
}
|
||||
protected MapRealmEntity() {}
|
||||
|
||||
public MapRealmEntity(String id) {
|
||||
this.id = id;
|
||||
|
@ -143,6 +141,13 @@ public class MapRealmEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated
|
||||
|
|
|
@ -42,14 +42,9 @@ public class MapRoleEntity implements AbstractEntity, UpdatableEntity {
|
|||
*/
|
||||
protected boolean updated;
|
||||
|
||||
protected MapRoleEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
protected MapRoleEntity() {}
|
||||
|
||||
public MapRoleEntity(String id, String realmId) {
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
@ -59,6 +54,13 @@ public class MapRoleEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
|
|
@ -214,7 +214,7 @@ public class ConcurrentHashMapKeycloakTransaction<K, V extends AbstractEntity &
|
|||
if (key == null) {
|
||||
K newKey = keyConvertor.yieldNewUniqueKey();
|
||||
key = keyConvertor.keyToString(newKey);
|
||||
value = Serialization.from(value, key);
|
||||
value.setId(key);
|
||||
}
|
||||
addTask(key, new CreateOperation(value));
|
||||
return value;
|
||||
|
|
|
@ -62,7 +62,7 @@ public class ConcurrentHashMapStorage<K, V extends AbstractEntity & UpdatableEnt
|
|||
K key = keyConvertor.fromStringSafe(value.getId());
|
||||
if (key == null) {
|
||||
key = keyConvertor.yieldNewUniqueKey();
|
||||
value = Serialization.from(value, keyConvertor.keyToString(key));
|
||||
value.setId(keyConvertor.keyToString(key));
|
||||
}
|
||||
store.putIfAbsent(key, value);
|
||||
return value;
|
||||
|
|
|
@ -42,8 +42,8 @@ import java.util.stream.Stream;
|
|||
*/
|
||||
public class MapUserEntity implements AbstractEntity, UpdatableEntity {
|
||||
|
||||
private final String id;
|
||||
private final String realmId;
|
||||
private String id;
|
||||
private String realmId;
|
||||
|
||||
private String username;
|
||||
private String firstName;
|
||||
|
@ -71,14 +71,9 @@ public class MapUserEntity implements AbstractEntity, UpdatableEntity {
|
|||
*/
|
||||
protected boolean updated;
|
||||
|
||||
protected MapUserEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
protected MapUserEntity() {}
|
||||
|
||||
public MapUserEntity(String id, String realmId) {
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
@ -88,6 +83,13 @@ public class MapUserEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated
|
||||
|
@ -100,6 +102,11 @@ public class MapUserEntity implements AbstractEntity, UpdatableEntity {
|
|||
return realmId;
|
||||
}
|
||||
|
||||
public void setRealmId(String realmId) {
|
||||
this.updated |= !Objects.equals(this.realmId, realmId);
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
|
|
@ -52,16 +52,9 @@ public class MapAuthenticatedClientSessionEntity implements AbstractEntity, Upda
|
|||
|
||||
private boolean offline;
|
||||
|
||||
public MapAuthenticatedClientSessionEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
public MapAuthenticatedClientSessionEntity() {}
|
||||
|
||||
public MapAuthenticatedClientSessionEntity(String id, String userSessionId, String realmId, String clientId, boolean offline) {
|
||||
Objects.requireNonNull(userSessionId, "userSessionId");
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
Objects.requireNonNull(clientId, "clientId");
|
||||
|
||||
this.id = id;
|
||||
this.userSessionId = userSessionId;
|
||||
this.realmId = realmId;
|
||||
|
@ -75,6 +68,13 @@ public class MapAuthenticatedClientSessionEntity implements AbstractEntity, Upda
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
|
|
@ -69,14 +69,9 @@ public class MapUserSessionEntity implements AbstractEntity, UpdatableEntity {
|
|||
|
||||
private boolean offline;
|
||||
|
||||
public MapUserSessionEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
public MapUserSessionEntity() {}
|
||||
|
||||
public MapUserSessionEntity(String id, String realmId) {
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
@ -103,6 +98,13 @@ public class MapUserSessionEntity implements AbstractEntity, UpdatableEntity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
if (this.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
this.id = id;
|
||||
this.updated |= id != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
|
|
Loading…
Reference in a new issue