remove old logic

This commit is contained in:
Efstratios Giannopoulos 2024-02-06 16:38:18 +02:00
parent fbe9683842
commit a52a3758d5
24 changed files with 26 additions and 452 deletions

View File

@ -5,8 +5,6 @@ import eu.eudat.commons.enums.DescriptionStatus;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.data.converters.enums.DescriptionStatusConverter; import eu.eudat.data.converters.enums.DescriptionStatusConverter;
import eu.eudat.data.converters.enums.IsActiveConverter; import eu.eudat.data.converters.enums.IsActiveConverter;
import eu.eudat.data.old.helpers.EntityBinder;
import eu.eudat.data.old.queryableentity.DataEntity;
import eu.eudat.data.tenant.TenantScopedBaseEntity; import eu.eudat.data.tenant.TenantScopedBaseEntity;
import jakarta.persistence.*; import jakarta.persistence.*;

View File

@ -6,14 +6,12 @@ import eu.eudat.commons.enums.IsActive;
import eu.eudat.data.converters.enums.DescriptionTemplateStatusConverter; import eu.eudat.data.converters.enums.DescriptionTemplateStatusConverter;
import eu.eudat.data.converters.enums.DescriptionTemplateVersionStatusConverter; import eu.eudat.data.converters.enums.DescriptionTemplateVersionStatusConverter;
import eu.eudat.data.converters.enums.IsActiveConverter; import eu.eudat.data.converters.enums.IsActiveConverter;
import eu.eudat.data.old.queryableentity.DataEntity;
import eu.eudat.data.tenant.TenantScopedBaseEntity; import eu.eudat.data.tenant.TenantScopedBaseEntity;
import eu.eudat.data.types.SQLXMLType; import eu.eudat.data.types.SQLXMLType;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
import java.time.Instant; import java.time.Instant;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@Entity @Entity

View File

@ -8,12 +8,10 @@ import eu.eudat.data.converters.enums.DmpAccessTypeNullableConverter;
import eu.eudat.data.converters.enums.DmpStatusConverter; import eu.eudat.data.converters.enums.DmpStatusConverter;
import eu.eudat.data.converters.enums.DmpVersionStatusConverter; import eu.eudat.data.converters.enums.DmpVersionStatusConverter;
import eu.eudat.data.converters.enums.IsActiveConverter; import eu.eudat.data.converters.enums.IsActiveConverter;
import eu.eudat.data.old.queryableentity.DataEntity;
import eu.eudat.data.tenant.TenantScopedBaseEntity; import eu.eudat.data.tenant.TenantScopedBaseEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.time.Instant; import java.time.Instant;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@Entity @Entity

View File

@ -1,12 +0,0 @@
package eu.eudat.data.old.queryableentity;
import jakarta.persistence.Tuple;
import java.util.List;
public interface DataEntity<T, K> {
void update(T entity);
K getKeys();
T buildFromTuple(List<Tuple> tuple, List<String> fields, String base);
}

View File

@ -1,7 +1,6 @@
package eu.eudat.model; package eu.eudat.model;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.data.old.queryableentity.DataEntity;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;

View File

@ -1,12 +0,0 @@
package eu.eudat.model.publicapi;
import eu.eudat.data.old.queryableentity.DataEntity;
public interface DataModel<T extends DataEntity<?,?>, M extends DataModel<?,?>> {
M fromDataModel(T entity);
T toDataModel() throws Exception;
String getHint();
}

View File

@ -1,22 +0,0 @@
package eu.eudat.model.publicapi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
public class HintedModelFactory {
private static final Logger logger = LoggerFactory.getLogger(HintedModelFactory.class);
public static <T extends DataModel<?,?>> String getHint(Class<T> clazz) {
try {
return clazz.getDeclaredConstructor().newInstance().getHint();
} catch (InstantiationException | IllegalAccessException e) {
logger.error(e.getMessage(), e);
return null;
} catch (InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,22 +0,0 @@
package eu.eudat.data.dao;
import eu.eudat.data.dao.databaselayer.service.DatabaseService;
import eu.eudat.data.old.queryableentity.DataEntity;
public class DatabaseAccess<T extends DataEntity> {
public DatabaseAccess(DatabaseService<T> databaseService) {
this.databaseService = databaseService;
}
private DatabaseService<T> databaseService;
public DatabaseService<T> getDatabaseService() {
return databaseService;
}
public void setDatabaseService(DatabaseService<T> databaseService) {
this.databaseService = databaseService;
}
}

View File

@ -1,22 +0,0 @@
package eu.eudat.data.dao;
import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
import javax.management.InvalidApplicationException;
import java.util.concurrent.CompletableFuture;
public interface DatabaseAccessLayer<T extends DataEntity, I> {
T createOrUpdate(T item);
CompletableFuture<T> createOrUpdateAsync(T item);
T find(I id) throws InvalidApplicationException;
T find(I id, String hint) throws InvalidApplicationException;
void delete(T item);
QueryableList<T> asQueryable();
}

View File

@ -2,7 +2,6 @@ package eu.eudat.data.dao.databaselayer.context;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.queryable.jpa.hibernatequeryablelist.QueryableHibernateList; import eu.eudat.queryable.jpa.hibernatequeryablelist.QueryableHibernateList;
import eu.eudat.data.old.queryableentity.DataEntity;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -13,7 +12,7 @@ import jakarta.persistence.PersistenceContext;
@Repository("databaseCtx") @Repository("databaseCtx")
public class DatabaseContext<T extends DataEntity> { public class DatabaseContext<T> {
@PersistenceContext @PersistenceContext
private EntityManager entityManager; private EntityManager entityManager;
@ -30,16 +29,17 @@ public class DatabaseContext<T extends DataEntity> {
@Transactional @Transactional
public T createOrUpdate(T item, Class<T> type) { public T createOrUpdate(T item, Class<T> type) {
EntityManager entityManager = this.entityManager; EntityManager entityManager = this.entityManager;
if (item.getKeys() != null) { // if (item.getKeys() != null) {
T oldItem = entityManager.find(type, item.getKeys()); // T oldItem = entityManager.find(type, item.getKeys());
if (oldItem != null) { // if (oldItem != null) {
oldItem.update(item); // oldItem.update(item);
entityManager.merge(oldItem); // entityManager.merge(oldItem);
return oldItem; // return oldItem;
} else { // } else {
entityManager.persist(item); // entityManager.persist(item);
} // }
} else entityManager.persist(item); // } else
entityManager.persist(item);
return item; return item;
} }

View File

@ -3,7 +3,6 @@ package eu.eudat.data.dao.databaselayer.service;
import eu.eudat.data.dao.databaselayer.context.DatabaseContext; import eu.eudat.data.dao.databaselayer.context.DatabaseContext;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -12,7 +11,7 @@ import java.util.Set;
@Service("databaseService") @Service("databaseService")
public class DatabaseService<T extends DataEntity> { public class DatabaseService<T> {
private DatabaseContext<T> databaseCtx; private DatabaseContext<T> databaseCtx;

View File

@ -4,7 +4,6 @@ import eu.eudat.data.query.definition.TableQuery;
import eu.eudat.data.query.definition.helpers.ColumnOrderings; import eu.eudat.data.query.definition.helpers.ColumnOrderings;
import eu.eudat.data.query.definition.helpers.Ordering; import eu.eudat.data.query.definition.helpers.Ordering;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;

View File

@ -1,7 +1,6 @@
package eu.eudat.data.query.definition; package eu.eudat.data.query.definition;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
/** /**
* Created by ikalyvas on 3/21/2018. * Created by ikalyvas on 3/21/2018.

View File

@ -2,7 +2,6 @@ package eu.eudat.data.query.definition;
import eu.eudat.data.dao.criteria.Criteria; import eu.eudat.data.dao.criteria.Criteria;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
/** /**
* Created by ikalyvas on 3/21/2018. * Created by ikalyvas on 3/21/2018.

View File

@ -2,7 +2,6 @@ package eu.eudat.data.query.definition;
import eu.eudat.data.dao.criteria.Criteria; import eu.eudat.data.dao.criteria.Criteria;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -13,7 +12,7 @@ public abstract class Query<C extends Criteria<T>, T> implements CriteriaQuery<C
@ApiModelProperty(value = "query", name = "query", dataType = "String", hidden = true) @ApiModelProperty(value = "query", name = "query", dataType = "String", hidden = true)
private QueryableList<T> query; private QueryableList<T> query;
public static class QueryBuilder<C extends Criteria<T>, T extends DataEntity, Q extends Query<C, T>> { public static class QueryBuilder<C extends Criteria<T>, T, Q extends Query<C, T>> {
private C criteria; private C criteria;
private QueryableList<T> query; private QueryableList<T> query;
private Class<Q> tClass; private Class<Q> tClass;

View File

@ -5,7 +5,6 @@ import eu.eudat.data.dao.criteria.Criteria;
import eu.eudat.data.query.definition.helpers.ColumnOrderings; import eu.eudat.data.query.definition.helpers.ColumnOrderings;
import eu.eudat.data.query.definition.helpers.SelectionFields; import eu.eudat.data.query.definition.helpers.SelectionFields;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;

View File

@ -1,30 +0,0 @@
package eu.eudat.query;
import eu.eudat.data.dao.DatabaseAccessLayer;
import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
import javax.management.InvalidApplicationException;
import java.util.LinkedList;
import java.util.List;
public abstract class Query<T extends DataEntity, K> {
protected DatabaseAccessLayer<T, K> databaseAccessLayer;
private List<String> selectionFields = new LinkedList<>();
public Query(DatabaseAccessLayer<T, K> databaseAccessLayer, List<String> selectionFields) {
this.databaseAccessLayer = databaseAccessLayer;
this.selectionFields = selectionFields;
}
public Query(DatabaseAccessLayer<T, K> databaseAccessLayer) {
this.databaseAccessLayer = databaseAccessLayer;
}
public abstract QueryableList<T> getQuery() throws InvalidApplicationException;
protected List<String> getSelectionFields() {
return selectionFields;
}
}

View File

@ -1,6 +1,5 @@
package eu.eudat.queryable; package eu.eudat.queryable;
import eu.eudat.data.old.queryableentity.DataEntity;
import eu.eudat.queryable.jpa.predicates.*; import eu.eudat.queryable.jpa.predicates.*;
import eu.eudat.queryable.types.SelectionField; import eu.eudat.queryable.types.SelectionField;

View File

@ -1,7 +1,6 @@
package eu.eudat.queryable.jpa.hibernatequeryablelist; package eu.eudat.queryable.jpa.hibernatequeryablelist;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.old.queryableentity.DataEntity;
import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.QueryableList;
import eu.eudat.queryable.collector.Collector; import eu.eudat.queryable.collector.Collector;
import eu.eudat.queryable.exceptions.NotSingleResultException; import eu.eudat.queryable.exceptions.NotSingleResultException;
@ -21,7 +20,7 @@ import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class QueryableHibernateList<T extends DataEntity> implements QueryableList<T> { public class QueryableHibernateList<T> implements QueryableList<T> {
private static final Logger logger = LoggerFactory.getLogger(QueryableHibernateList.class); private static final Logger logger = LoggerFactory.getLogger(QueryableHibernateList.class);
@ -302,11 +301,11 @@ public class QueryableHibernateList<T extends DataEntity> implements QueryableLi
typedQuery.setFirstResult(this.offset); typedQuery.setFirstResult(this.offset);
if (this.length != null) if (this.length != null)
typedQuery.setMaxResults(this.length); typedQuery.setMaxResults(this.length);
if (this.hint != null) { // if (this.hint != null) {
List ids = typedQuery.getResultList().stream().map(item -> item.getKeys()).collect(Collectors.toList()); // List ids = typedQuery.getResultList().stream().map(item -> item.getKeys()).collect(Collectors.toList());
if (ids != null && !ids.isEmpty()) // if (ids != null && !ids.isEmpty())
typedQuery = queryWithHint(ids); // typedQuery = queryWithHint(ids);
} // }
return typedQuery.getResultList(); return typedQuery.getResultList();
} }
@ -340,7 +339,8 @@ public class QueryableHibernateList<T extends DataEntity> implements QueryableLi
.collect(Collectors.groupingBy(x -> x.get("id"))); .collect(Collectors.groupingBy(x -> x.get("id")));
return CompletableFuture.supplyAsync(() -> results.stream().map(x -> { return CompletableFuture.supplyAsync(() -> results.stream().map(x -> {
try { try {
return (T) this.tClass.newInstance().buildFromTuple(groupedResults.get(x.get("id")), this.fields, ""); // return (T) this.tClass.newInstance().buildFromTuple(groupedResults.get(x.get("id")), this.fields, "");
return (T) this.tClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) { } catch (InstantiationException | IllegalAccessException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
@ -357,9 +357,9 @@ public class QueryableHibernateList<T extends DataEntity> implements QueryableLi
typedQuery.setMaxResults(this.length); typedQuery.setMaxResults(this.length);
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
if (this.hint != null) { if (this.hint != null) {
List ids = typedQuery.getResultList().stream().map(item -> item.getKeys()).collect(Collectors.toList()); // List ids = typedQuery.getResultList().stream().map(item -> item.getKeys()).collect(Collectors.toList());
if (ids != null && !ids.isEmpty()) // if (ids != null && !ids.isEmpty())
return queryWithHint(ids).getResultList(); // return queryWithHint(ids).getResultList();
} }
return typedQuery.getResultList(); return typedQuery.getResultList();
}); });

View File

@ -1,59 +0,0 @@
package eu.eudat.criteria;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import eu.eudat.criteria.entities.Criteria;
import eu.eudat.query.UserQuery;
import java.io.IOException;
import java.util.*;
public class UserCriteria {
private Criteria<UUID> id;
private Criteria<String> email;
public Criteria<UUID> getId() {
return id;
}
public void setId(JsonNode jsonNode) throws IOException {
if (jsonNode.getNodeType().equals(JsonNodeType.STRING)) {
Criteria<UUID> criteria = new Criteria<>();
criteria.setAs(jsonNode.asText());
this.id = criteria;
} else if (jsonNode.getNodeType().equals(JsonNodeType.OBJECT)) {
ObjectReader reader = new ObjectMapper().readerFor(new TypeReference<Criteria<UUID>>() {
});
this.id = reader.readValue(jsonNode);
}
}
public Criteria<String> getEmail() {
return email;
}
public void setEmail(JsonNode jsonNode) throws IOException {
if (jsonNode.getNodeType().equals(JsonNodeType.STRING)) {
Criteria<String> criteria = new Criteria<>();
criteria.setAs(jsonNode.asText());
this.email = criteria;
} else if (jsonNode.getNodeType().equals(JsonNodeType.OBJECT)) {
ObjectReader reader = new ObjectMapper().readerFor(new TypeReference<Criteria<String>>() {
});
this.email = reader.readValue(jsonNode);
}
}
protected List<String> buildFields(String path) {
Set<String> fields = new LinkedHashSet<>();
path = path != null && !path.isEmpty() ? path + "." : "";
if (this.id != null) fields.add(path + this.id.getAs());
if (this.email != null) fields.add(path + this.email.getAs());
if (!fields.contains(path + "id")) fields.add(path + "id");
return new LinkedList<>(fields);
}
}

View File

@ -1,56 +0,0 @@
package eu.eudat.logic.managers;
import eu.eudat.data.query.definition.TableQuery;
import eu.eudat.data.query.definition.helpers.ColumnOrderings;
import eu.eudat.data.query.definition.helpers.Ordering;
import eu.eudat.queryable.QueryableList;
import eu.eudat.data.old.queryableentity.DataEntity;
import java.util.Arrays;
import java.util.Collection;
public class PaginationManager {
public static <T extends DataEntity> QueryableList<T> applyPaging(QueryableList<T> items, TableQuery tableRequest) throws Exception {
if (tableRequest.getOrderings() != null) applyOrder(items, tableRequest);
if (tableRequest.getLength() != null) items.take(tableRequest.getLength());
if (tableRequest.getOffset() != null) items.skip(tableRequest.getOffset());
if (tableRequest.getSelection() != null && tableRequest.getSelection().getFields() != null && tableRequest.getSelection().getFields().length > 0)
items.withFields(Arrays.asList(tableRequest.getSelection().getFields()));
return items;
}
public static <T extends DataEntity> void applyOrder(QueryableList<T> items, TableQuery tableRequest) throws Exception {
ColumnOrderings columnOrderings = tableRequest.getOrderings();
for (Ordering ordering : columnOrderings.getFieldOrderings()) {
if (ordering.getOrderByType() == Ordering.OrderByType.ASC)
applyAscOrder(items, ordering);
if (ordering.getOrderByType() == Ordering.OrderByType.DESC) {
applyDescOrder(items, ordering);
}
}
return;
}
private static <T extends DataEntity> void applyAscOrder(QueryableList<T> items, Ordering ordering) {
if (ordering.getColumnType() == Ordering.ColumnType.COUNT) {
items.orderBy((builder, root) -> builder.asc(builder.size(root.<Collection>get(ordering.getFieldName()))));
} else if (ordering.getColumnType() == Ordering.ColumnType.JOIN_COLUMN) {
String[] fields = ordering.getFieldName().split(":");
items.orderBy((builder, root) -> builder.asc(root.get(fields[0]).get(fields[1])));
} else {
items.orderBy((builder, root) -> builder.asc(root.get(ordering.getFieldName())));
}
}
private static <T extends DataEntity> void applyDescOrder(QueryableList<T> items, Ordering ordering) {
if (ordering.getColumnType() == Ordering.ColumnType.COUNT) {
items.orderBy((builder, root) -> builder.desc(builder.size(root.<Collection>get(ordering.getFieldName()))));
} else if (ordering.getColumnType() == Ordering.ColumnType.JOIN_COLUMN) {
String[] fields = ordering.getFieldName().split(":");
items.orderBy((builder, root) -> builder.desc(root.get(fields[0]).get(fields[1])));
} else {
items.orderBy((builder, root) -> builder.desc(root.get(ordering.getFieldName())));
}
}
}

View File

@ -1,9 +1,7 @@
package eu.eudat.models; package eu.eudat.models;
import eu.eudat.data.old.queryableentity.DataEntity; public interface DataModel<T, M extends DataModel> {
public interface DataModel<T extends DataEntity, M extends DataModel> {
M fromDataModel(T entity); M fromDataModel(T entity);
T toDataModel() throws Exception; T toDataModel() throws Exception;

View File

@ -1,147 +0,0 @@
package eu.eudat.models.data.dashboard.recent.model;
import eu.eudat.model.DmpUser;
import eu.eudat.models.DataModel;
import eu.eudat.data.old.queryableentity.DataEntity;
import java.util.Date;
import java.util.List;
public abstract class RecentActivityModel<T extends DataEntity, S extends DataModel> implements DataModel<T, S> {
private String id;
private String title;
private Date created;
private Date modified;
private int status;
private int version;
private String grant;
private Date finalizedAt;
private Date publishedAt;
private int type;
private List<DmpUser> users;
private Boolean isPublic;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public String getGrant() {
return grant;
}
public void setGrant(String grant) {
this.grant = grant;
}
public Date getFinalizedAt() {
return finalizedAt;
}
public void setFinalizedAt(Date finalizedAt) {
this.finalizedAt = finalizedAt;
}
public Date getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(Date publishedAt) {
this.publishedAt = publishedAt;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public List<DmpUser> getUsers() {
return users;
}
public void setUsers(List<DmpUser> users) {
this.users = users;
}
public Boolean getPublic() {
return isPublic;
}
public void setPublic(Boolean aPublic) {
isPublic = aPublic;
}
public abstract RecentActivityModel fromEntity(T entity);
public enum RecentActivityType {
DMP(2), DATASET(1);
private final int index;
RecentActivityType(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
public static RecentActivityType fromIndex(int index) {
switch (index) {
case 2:
return DMP;
case 1:
return DATASET;
default:
throw new IllegalArgumentException("Recent Activity Type : \"" + index + "\" is not supported.");
}
}
}
}

View File

@ -1,28 +0,0 @@
package eu.eudat.models.data.urls;
import eu.eudat.models.DataModel;
import eu.eudat.data.old.queryableentity.DataEntity;
/**
* Created by ikalyvas on 3/19/2018.
*/
public abstract class UrlListing<T extends DataEntity,M extends DataModel> implements DataModel<T,M>{
private String label;
private String url;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}