/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package hr.fer.zemris.vhdllab.entity; import hr.fer.zemris.vhdllab.validation.NameFormatConstraint; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.validator.NotNull; @Entity @Table(name = "files", uniqueConstraints = { @UniqueConstraint(columnNames = { "project_id", "name" }) }) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class File extends FileInfo { private static final long serialVersionUID = -2001411661196642883L; @NotNull @ManyToOne(fetch = FetchType.EAGER, optional = false) @JoinColumn(name = "project_id", updatable = false) private Project project; private transient Project postRemoveProjectReference; public File() { super(); } public File(String name, FileType type, String data) { super(name, type, data); } public File(File clone) { this(clone, false); } public File(File clone, boolean setProjectReference) { this(clone, setProjectReference ? clone.getProject() : null); } public File(File clone, Project project) { super(clone); setProject(project); } @NameFormatConstraint @Override public String getName() { return super.getName(); } public Project getProject() { return project; } public void setProject(Project project) { if (project == null) { setPostRemoveProjectReference(this.project); } this.project = project; } /** * This is a leftover reference to a project that this file used to belong. * When a file wants to be removed it need to be detached from project-file * relationship by calling {@link Project#removeFile(File)} method. This * will set project (property) to null. However this information is still * required on post remove event (see {@link HistoryListener}) in order to * set deletedOn timestamp on {@link FileHistory}. For that reason this * property holds a reference to project even after project-file * relationship (for this file) has been severed. * <p> * Please note that this method will destroy reference to a project once its * been called. In other words first time its called it will return * reference to a project but each other time it will return * <code>null</code>. Reason for this is to minimize problem with garbage * collection. * </p> * <p> * THIS METHOD SHOULD NOT BE CALLED BY ANY OTHER THEN POST REMOVE EVENT * METHOD IN {@link HistoryListener}!! * </p> * * @return the post remove project reference or <code>null</code> if it has * not been set */ Project getPostRemoveProjectReference() { if (this.postRemoveProjectReference != null) { Project projectReference = this.postRemoveProjectReference; setPostRemoveProjectReference(null); return projectReference; } return null; } /** * Sets a post remove project reference * * @param project * the post remove project reference to set * @see #getPostRemoveProjectReference() */ void setPostRemoveProjectReference(Project project) { this.postRemoveProjectReference = project; } @Override public int hashCode() { return new HashCodeBuilder() .appendSuper(super.hashCode()) .append(getProject()) .toHashCode(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof File)) return false; File other = (File) obj; return new EqualsBuilder() .appendSuper(super.equals(obj)) .append(getProject(), other.getProject()) .isEquals(); } @Override public String toString() { Project p = getProject(); Integer pId = null; String pUserId = null; String pName = null; if (p != null) { pId = p.getId(); pUserId = p.getUserId(); pName = p.getName(); } return new ToStringBuilder(this) .appendSuper(super.toString()) .append("projectId", pId) .append("projectUserId", pUserId) .append("projectName", pName) .toString(); } }