package org.pentaho.platform.api.repository;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* Immutable repository file. Use the {@link Builder} to create instances.
*
* <p>
* This class should use only GWT-emulated types.
* </p>
*
* @author mlowery
*/
public class RepositoryFile implements Comparable<RepositoryFile>/*, Serializable*/ {
// ~ Static fields/initializers ======================================================================================
private static final long serialVersionUID = -6955142003557786114L;
public static final String SEPARATOR = "/"; //$NON-NLS-1$
/**
* Key used in {@link #titleMap} or {@link #descriptionMap} that indicates what string to use when no locale
* information is available.
*/
public static final String ROOT_LOCALE = "rootLocale"; //$NON-NLS-1$
// ~ Instance fields =================================================================================================
private String name;
private Serializable id;
/**
* Read-only.
*/
private Date createdDate;
/**
* Read-only.
*/
private Date lastModifiedDate;
private boolean folder;
/**
* Read-only.
*/
private String absolutePath;
private boolean hidden;
private boolean versioned;
/**
* The version name or number. Read-only.
*/
private Serializable versionId;
/**
* Locked status. Read-only.
*/
private boolean locked;
/**
* Username of the owner of the lock. Read-only. {@code null} if file not locked.
*/
private String lockOwner;
/**
* Message left by the owner when he locked the file. Read-only. {@code null} if file not locked.
*/
private String lockMessage;
/**
* The date that this lock was created. Read-only. {@code null} if file not locked.
*/
private Date lockDate;
/**
* The owner of this file. Usually plays a role in access control. Read-only.
*/
private RepositoryFileSid owner;
/**
* A title for the file for the current locale. If locale not available, the file's name is returned. Read-only.
*/
private String title;
/**
* A description of the file for the current locale. Read-only.
*/
private String description;
/**
* A map for titles. Keys are locale strings and values are titles. Write-only. {@code null} value means that no
* title will be created or updated.
*/
private Map<String, String> titleMap;
/**
* A map for descriptions. Keys are locale strings and values are descriptions. Write-only. {@code null} value means
* that no description will be created or updated.
*/
private Map<String, String> descriptionMap;
/**
* The locale string with which locale-sensitive fields (like title) are populated. Used in {@link #equals(Object)}
* calculation to guarantee caching works correctly. Read-only.
*/
private String locale;
// ~ Constructors ====================================================================================================
public RepositoryFile(final String name) {
super();
this.name = name;
}
public RepositoryFile(final Serializable id, final String name) {
super();
this.name = name;
this.id = id;
}
// ~ Methods =========================================================================================================
public String getName() {
return name;
}
public Serializable getId() {
return id;
}
public Date getCreatedDate() {
// defensive copy
return (createdDate != null ? new Date(createdDate.getTime()) : null);
}
public Date getLastModifiedDate() {
// defensive copy
return (lastModifiedDate != null ? new Date(lastModifiedDate.getTime()) : null);
}
public boolean isFolder() {
return folder;
}
public String getAbsolutePath() {
return absolutePath;
}
public boolean isHidden() {
return hidden;
}
public boolean isVersioned() {
return versioned;
}
public Serializable getVersionId() {
return versionId;
}
public boolean isLocked() {
return locked;
}
public String getLockOwner() {
return lockOwner;
}
public String getLockMessage() {
return lockMessage;
}
public Date getLockDate() {
// defensive copy
return (lockDate != null ? new Date(lockDate.getTime()) : null);
}
public RepositoryFileSid getOwner() {
return owner;
}
/**
* Returns title for current locale or file name if not available.
*/
public String getTitle() {
return title != null ? title : name;
}
public String getDescription() {
return description;
}
public Map<String, String> getTitleMap() {
// defensive copy
return titleMap == null ? null : new HashMap<String, String>(titleMap);
}
public Map<String, String> getDescriptionMap() {
// defensive copy
return descriptionMap == null ? null : new HashMap<String, String>(descriptionMap);
}
public String getLocale() {
return locale;
}
@Override
public String toString() {
// TODO mlowery remove this to be GWT-compatible
return ToStringBuilder.reflectionToString(this);
}
public static class Builder {
private String name;
private Serializable id;
private Date createdDate;
private Date lastModifiedDate;
private boolean folder;
private String absolutePath;
private boolean hidden;
private boolean versioned;
private Serializable versionId;
private boolean locked;
private String lockOwner;
private String lockMessage;
private Date lockDate;
private RepositoryFileSid owner;
private String title;
private String description;
private Map<String, String> titleMap;
private Map<String, String> descriptionMap;
private String locale;
public Builder(final String name) {
assertHasText(name);
this.name = name;
this.clearTitleMap();
}
public Builder(final Serializable id, final String name) {
assertNotNull(id);
this.name = name;
this.id = id;
this.clearTitleMap();
}
public Builder(final RepositoryFile other) {
this(other.id, other.name);
this.absolutePath(other.absolutePath).createdDate(other.createdDate).folder(other.folder).lastModificationDate(
other.lastModifiedDate).versioned(other.versioned).hidden(other.hidden).versionId(other.versionId).locked(
other.locked).lockDate(other.lockDate).lockOwner(other.lockOwner).lockMessage(other.lockMessage).owner(
other.owner).title(other.title).description(other.description).titleMap(other.titleMap).descriptionMap(
other.descriptionMap).locale(other.locale);
}
public RepositoryFile build() {
RepositoryFile result = new RepositoryFile(id, name);
result.createdDate = this.createdDate;
result.lastModifiedDate = this.lastModifiedDate;
result.folder = this.folder;
result.absolutePath = this.absolutePath;
result.hidden = this.hidden;
result.versioned = this.versioned;
result.versionId = this.versionId;
result.locked = this.locked;
result.lockOwner = this.lockOwner;
result.lockMessage = this.lockMessage;
result.lockDate = this.lockDate;
result.owner = this.owner;
result.title = this.title;
result.description = this.description;
result.titleMap = this.titleMap;
result.descriptionMap = this.descriptionMap;
result.locale = this.locale;
return result;
}
public Builder createdDate(final Date createdDate) {
// defensive copy
this.createdDate = (createdDate != null ? new Date(createdDate.getTime()) : null);
return this;
}
public Builder lastModificationDate(final Date lastModifiedDate) {
// defensive copy
this.lastModifiedDate = (lastModifiedDate != null ? new Date(lastModifiedDate.getTime()) : null);
return this;
}
public Builder folder(final boolean folder) {
this.folder = folder;
return this;
}
public Builder absolutePath(final String absolutePath) {
this.absolutePath = absolutePath;
return this;
}
public Builder hidden(final boolean hidden) {
this.hidden = hidden;
return this;
}
public Builder versioned(final boolean versioned) {
this.versioned = versioned;
return this;
}
public Builder versionId(final Serializable versionId) {
this.versionId = versionId;
return this;
}
public Builder locked(final boolean locked) {
this.locked = locked;
return this;
}
public Builder lockOwner(final String lockOwner) {
this.lockOwner = lockOwner;
return this;
}
public Builder lockMessage(final String lockMessage) {
this.lockMessage = lockMessage;
return this;
}
public Builder lockDate(final Date lockDate) {
// defensive copy
this.lockDate = (lockDate != null ? new Date(lockDate.getTime()) : null);
return this;
}
public Builder owner(final RepositoryFileSid owner) {
this.owner = owner;
return this;
}
public Builder title(final String title) {
this.title = title;
return this;
}
public Builder description(final String description) {
this.description = description;
return this;
}
public Builder titleMap(final Map<String, String> titleMap) {
// defensive copy
this.titleMap = (titleMap != null ? new HashMap<String, String>(titleMap) : null);
return this;
}
public Builder clearTitleMap() {
if (this.titleMap != null) {
this.titleMap.clear();
}
return this;
}
public Builder title(final String localeString, final String title) {
initTitleMap();
this.titleMap.put(localeString, title);
return this;
}
private void initTitleMap() {
if (this.titleMap == null) {
this.titleMap = new HashMap<String, String>();
this.titleMap.put(ROOT_LOCALE, this.name);
}
}
public Builder descriptionMap(final Map<String, String> descriptionMap) {
// defensive copy
this.descriptionMap = (descriptionMap != null ? new HashMap<String, String>(descriptionMap) : descriptionMap);
return this;
}
public Builder clearDescriptionMap() {
if (this.descriptionMap != null) {
this.descriptionMap.clear();
}
return this;
}
public Builder description(final String localeString, final String description) {
initDescriptionMap();
this.descriptionMap.put(localeString, description);
return this;
}
private void initDescriptionMap() {
if (this.descriptionMap == null) {
this.descriptionMap = new HashMap<String, String>();
}
}
public Builder locale(final String locale) {
this.locale = locale;
return this;
}
/**
* Implemented here to maintain GWT-compatibility.
*/
protected void assertHasText(final String in) {
if (in == null || in.length() == 0 || in.trim().length() == 0) {
throw new IllegalArgumentException(
"[Assertion failed] - this String argument must have text; it must not be null, empty, or blank");
}
}
/**
* Implemented here to maintain GWT-compatibility.
*/
protected void assertTrue(final boolean expression) {
if (!expression) {
throw new IllegalArgumentException("[Assertion failed] - this expression must be true");
}
}
/**
* Implemented here to maintain GWT-compatibility.
*/
private void assertNotNull(final Object in) {
if (in == null) {
throw new IllegalArgumentException("[Assertion failed] - this argument is required; it must not be null");
}
}
}
public int compareTo(final RepositoryFile other) {
if (other == null) {
throw new NullPointerException(); // per Comparable contract
}
if (equals(other)) {
return 0;
}
// either this or other has a null id; fall back on name
return getTitle().compareTo(other.getTitle());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((locale == null) ? 0 : locale.hashCode());
result = prime * result + ((versionId == null) ? 0 : versionId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RepositoryFile other = (RepositoryFile) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (locale == null) {
if (other.locale != null)
return false;
} else if (!locale.equals(other.locale))
return false;
if (versionId == null) {
if (other.versionId != null)
return false;
} else if (!versionId.equals(other.versionId))
return false;
return true;
}
}