Skip to content

chore: annotation mapping for Dashboard #21413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
339 changes: 336 additions & 3 deletions dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/Dashboard.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,51 +31,132 @@

import static org.hisp.dhis.common.DxfNamespaces.DXF_2_0;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderColumn;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Type;
import org.hisp.dhis.attribute.AttributeValues;
import org.hisp.dhis.common.BaseIdentifiableObject;
import org.hisp.dhis.common.BaseNameableObject;
import org.hisp.dhis.common.BaseMetadataObject;
import org.hisp.dhis.common.DxfNamespaces;
import org.hisp.dhis.common.MetadataObject;
import org.hisp.dhis.common.IdScheme;
import org.hisp.dhis.common.IdentifiableObject;
import org.hisp.dhis.common.IdentifiableProperty;
import org.hisp.dhis.common.OpenApi;
import org.hisp.dhis.common.annotation.Description;
import org.hisp.dhis.dashboard.design.ItemConfig;
import org.hisp.dhis.dashboard.design.Layout;
import org.hisp.dhis.dashboard.embedded.EmbeddedDashboard;
import org.hisp.dhis.schema.PropertyType;
import org.hisp.dhis.schema.annotation.Property;
import org.hisp.dhis.schema.annotation.Property.Value;
import org.hisp.dhis.schema.annotation.PropertyRange;
import org.hisp.dhis.schema.annotation.PropertyTransformer;
import org.hisp.dhis.schema.transformer.UserPropertyTransformer;
import org.hisp.dhis.security.acl.Access;
import org.hisp.dhis.translation.Translation;
import org.hisp.dhis.user.User;
import org.hisp.dhis.user.UserDetails;
import org.hisp.dhis.user.sharing.Sharing;

/**
* Encapsulates information about an embedded dashboard. An embedded dashboard is typically loaded
* from an external provider.
*
* @author Lars Helge Overland
*/
@Entity
@Table(name = "dashboard")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NoArgsConstructor
@JacksonXmlRootElement(localName = "dashboard", namespace = DxfNamespaces.DXF_2_0)
public class Dashboard extends BaseNameableObject implements MetadataObject {
public class Dashboard extends BaseMetadataObject implements IdentifiableObject {
public static final int MAX_ITEMS = 40;

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "dashboardid")
private long id;

@Column(name = "code", unique = true, length = 50)
private String code;

@Column(name = "name", nullable = false, length = 230)
private String name;

private String description;

@JoinTable(
name = "dashboard_items",
joinColumns = @JoinColumn(
name = "dashboardid",
foreignKey = @ForeignKey(name = "fk_dashboard_items_dashboardid")),
inverseJoinColumns = @JoinColumn(
name = "dashboarditemid",
foreignKey = @ForeignKey(name = "fk_dashboard_items_dashboarditemid")))
@OrderColumn(name = "sort_order")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<DashboardItem> items = new ArrayList<>();

@Type(type = "jblDashboardLayout")
private Layout layout;

@Type(type = "jbDashboardItemConfig")
private ItemConfig itemConfig;

/**
* Whether filter dimensions are restricted for the dashboard. The allowed filter dimensions are
* specified by {@link Dashboard#allowedFilters}.
*/
@Column(name = "restrictfilters")
private boolean restrictFilters;

/** Allowed filter dimensions (if any) which may be used for the dashboard. */
@Type(type = "jbList")
@Column(name = "allowedfilters")
private List<String> allowedFilters = new ArrayList<>();

/** Optional, only set if this dashboard is embedded and loaded from an external provider. */
@Type(type = "jbEmbeddedDashboard")
@Column(name = "embedded")
private EmbeddedDashboard embedded;

@Column(name = "sharing")
@Type(type = "jsbObjectSharing")
private Sharing sharing = new Sharing();

// ----------------------------------------------------------------
// Transient properties
// ----------------------------------------------------------------
private transient String href;

// -------------------------------------------------------------------------
// Constructors
// -------------------------------------------------------------------------
Expand Down Expand Up @@ -165,4 +246,256 @@
public void setEmbedded(EmbeddedDashboard embedded) {
this.embedded = embedded;
}

@Override
@JsonProperty
@JacksonXmlProperty(isAttribute = true)
@Description("The unique code for this Object.")
@Property(PropertyType.IDENTIFIER)
public String getCode() {
return code;
}

public void setCode(String code) {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
IdentifiableObject.setCode
; it is advisable to add an Override annotation.
this.code = code;
}

@Override
@JsonProperty
@JacksonXmlProperty(isAttribute = true)
@Description("The name of this Object. Required and unique.")
@PropertyRange(min = 1)
public String getName() {
return name;
}

public void setName(String name) {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
IdentifiableObject.setName
; it is advisable to add an Override annotation.
this.name = name;
}

@Override
@JsonProperty
@JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0)
public String getDisplayName() {
return name;
}

@Override
@JsonProperty
@JacksonXmlProperty(isAttribute = true)
@Description("The date this object was created.")
@Property(value = PropertyType.DATE, required = Value.FALSE)
public Date getCreated() {
return created;
}

@Override
@JsonProperty
@JacksonXmlProperty(isAttribute = true)
@Description("The date this object was last updated.")
@Property(value = PropertyType.DATE, required = Value.FALSE)
public Date getLastUpdated() {
return lastUpdated;
}

@Override
@OpenApi.Property(UserPropertyTransformer.UserDto.class)
@JsonProperty
@JsonSerialize(using = UserPropertyTransformer.JacksonSerialize.class)
@JsonDeserialize(using = UserPropertyTransformer.JacksonDeserialize.class)
@PropertyTransformer(UserPropertyTransformer.class)
@JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0)
public User getLastUpdatedBy() {
return lastUpdatedBy;
}

@Override
@OpenApi.Property(UserPropertyTransformer.UserDto.class)
@JsonProperty
@JsonSerialize(using = UserPropertyTransformer.JacksonSerialize.class)
@JsonDeserialize(using = UserPropertyTransformer.JacksonDeserialize.class)
@PropertyTransformer(UserPropertyTransformer.class)
@JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0)
public User getCreatedBy() {
return createdBy;
}

@Override
@OpenApi.Ignore
@JsonProperty
@JsonSerialize(using = UserPropertyTransformer.JacksonSerialize.class)
@JsonDeserialize(using = UserPropertyTransformer.JacksonDeserialize.class)
@PropertyTransformer(UserPropertyTransformer.class)
@JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0)
public User getUser() {
return createdBy;
}

@Override
public void setUser(User user) {
setCreatedBy(createdBy == null ? user : createdBy);
setOwner(user != null ? user.getUid() : null);
}

@Override
public AttributeValues getAttributeValues() {
return AttributeValues.empty();
}

@Override
public void setAttributeValues(AttributeValues attributeValues) {
// Do nothing, not supported
}

@Override
public void addAttributeValue(String attributeUid, String value) {
// Do nothing, not supported
}

@Override
public void removeAttributeValue(String attributeId) {
// Do nothing, not supported
}

@Override
public Set<String> getFavorites() {
return Set.of();
}

@Override
public boolean isFavorite() {
return false;
}

@Override
public boolean setAsFavorite(UserDetails user) {
return false;
}

@Override
public boolean removeAsFavorite(UserDetails user) {
return false;
}

@Override
public Access getAccess() {
return null;
}

@Override
public void setAccess(Access access) {
// Do nothing, not supported
}

@Override
public Sharing getSharing() {
if (sharing == null) {
sharing = new Sharing();
}
return sharing;
}

@Override
public void setSharing(Sharing sharing) {
this.sharing = sharing;
}

@Override
public void setOwner(String owner) {
getSharing().setOwner(owner);
}

@Override
public Set<Translation> getTranslations() {
return Set.of();
}

@Override
public void setTranslations(Set<Translation> translations) {
// Do nothing, not supported
}

@Override
public String getPropertyValue(IdScheme idScheme) {
if (idScheme.isNull() || idScheme.is(IdentifiableProperty.UID)) {
return uid;
} else if (idScheme.is(IdentifiableProperty.CODE)) {
return code;
} else if (idScheme.is(IdentifiableProperty.NAME)) {
return name;
} else if (idScheme.is(IdentifiableProperty.ID)) {
return id > 0 ? String.valueOf(id) : null;
} else if (idScheme.is(IdentifiableProperty.ATTRIBUTE)) {
return null;
}
return null;
}

@Override
public String getDisplayPropertyValue(IdScheme idScheme) {
if (idScheme.is(IdentifiableProperty.NAME)) {
return getDisplayName();
} else {
return getPropertyValue(idScheme);
}
}

@Override
@JsonIgnore
public long getId() {
return id;
}

@Override
public void setId(long id) {
this.id = id;
}

@Override
@JsonProperty(value = "id")
@JacksonXmlProperty(localName = "id", isAttribute = true)
@Description("The Unique Identifier for this Object.")
@Property(value = PropertyType.IDENTIFIER, required = Value.FALSE)
@PropertyRange(min = 11, max = 11)
public String getUid() {
return uid;
}

@Override
public void setUid(String uid) {
this.uid = uid;
}

@Override
public void setCreated(Date created) {
this.created = created;
}

@Override
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}

@Override
public void setLastUpdatedBy(User user) {
this.lastUpdatedBy = user;
}

@Override
public String getHref() {
return href;
}

@Override
public void setHref(String href) {
this.href = href;
}

public void setPublicAccess(String access) {
if (sharing == null) {
sharing = new Sharing();
}

sharing.setPublicAccess(access);
}
}
Loading