/* * * Copyright (C) 2007-2015 Licensed to the Comunes Association (CA) under * one or more contributor license agreements (see COPYRIGHT for details). * The CA licenses this file to you under the GNU Affero General Public * License version 3, (the "License"); you may not use this file except in * compliance with the License. This file is part of kune. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package cc.kune.domain; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.OrderBy; import javax.persistence.Table; import javax.persistence.Transient; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.search.annotations.ContainedIn; import org.hibernate.search.annotations.DocumentId; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Index; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Store; import cc.kune.core.shared.domain.utils.StateToken; import cc.kune.domain.utils.HasId; import cc.kune.domain.utils.HasStateToken; // TODO: Auto-generated Javadoc /** * The Class Container. * * @author danigb@gmail.com * @author vjrj@ourproject.org (Vicente J. Ruiz Jurado) */ @Entity @Indexed @Table(name = "containers") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Container implements HasId, HasStateToken { @OneToOne(cascade = CascadeType.ALL) private AccessLists accessLists; @LazyCollection(LazyCollectionOption.FALSE) @Fetch(FetchMode.JOIN) @OrderBy("createdOn DESC") @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) private Set<Container> childs; @OneToMany(cascade = CascadeType.ALL) private List<ContainerTranslation> containerTranslations; @LazyCollection(LazyCollectionOption.FALSE) @Fetch(FetchMode.JOIN) @ContainedIn @OrderBy("createdOn DESC") @OneToMany(mappedBy = "container", cascade = CascadeType.ALL, fetch = FetchType.EAGER) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) private Set<Content> contents; @org.hibernate.annotations.Index(name = "createdOn") @Basic(optional = false) private Long createdOn; @org.hibernate.annotations.Index(name = "deletedOn") @Basic(optional = true) private Date deletedOn; @Id @GeneratedValue @DocumentId Long id; @ManyToOne private I18nLanguage language; @Column @Field(index = Index.YES, store = Store.NO) private String name; @IndexedEmbedded(depth = 1, prefix = "owner_") @OneToOne private Group owner; // Parent/Child pattern: // http://www.hibernate.org/hib_docs/reference/en/html/example-parentchild.html // http://www.researchkitchen.co.uk/blog/archives/57 @LazyCollection(LazyCollectionOption.FALSE) @ManyToOne(fetch = FetchType.EAGER) @JoinColumn private Container parent; private String toolName; private String typeId; public Container() { this(null, null, null); } public Container(final String title, final Group group, final String toolName) { this.name = title; owner = group; this.toolName = toolName; this.contents = new HashSet<Content>(); this.childs = new HashSet<Container>(); this.createdOn = System.currentTimeMillis(); } public void addChild(final Container child) { child.setParent(this); childs.add(child); } public void addContent(final Content descriptor) { // FIXME: something related with lazy initialization (workaround using // size()) contents.size(); contents.add(descriptor); } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Container other = (Container) obj; if (id == null) { if (other.id != null) { return false; } } else if (!id.equals(other.id)) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } if (toolName == null) { if (other.toolName != null) { return false; } } else if (!toolName.equals(other.toolName)) { return false; } if (typeId == null) { if (other.typeId != null) { return false; } } else if (!typeId.equals(other.typeId)) { return false; } return true; } @Transient public List<Container> getAbsolutePath() { ArrayList<Container> path; if (isRoot()) { path = new ArrayList<Container>(); } else { path = new ArrayList<Container>((getParent().getAbsolutePath())); } path.add(this); return path; } @Transient public AccessLists getAccessLists() { return hasAccessList() ? accessLists : isRoot() ? new AccessLists(getOwner()) : getParent().getAccessLists(); } public List<ContainerTranslation> getAliases() { return containerTranslations; } public Set<Container> getChilds() { return childs; } public List<ContainerTranslation> getContainerTranslations() { return containerTranslations; } public Set<Content> getContents() { return contents; } public Long getCreatedOn() { return createdOn; } public Date getDeletedOn() { return deletedOn; } @Override public Long getId() { return id; } public I18nLanguage getLanguage() { return language; } public String getName() { return name; } public Group getOwner() { return owner; } public Container getParent() { return parent; } public StateToken getParentToken() { return parent != null ? parent.getStateToken() : null; } @Override @Transient public StateToken getStateToken() { return new StateToken(getOwner().getShortName(), getToolName(), getId()); } @Transient public String getStateTokenEncoded() { return getStateToken().getEncoded(); } public String getToolName() { return toolName; } public String getTypeId() { return typeId; } @Transient public boolean hasAccessList() { return accessLists != null; } @Transient public boolean isLeaf() { return childs.size() == 0 && contents.size() == 0; } @Transient public boolean isRoot() { return parent == null; } public void removeChild(final Container child) { // Adding hash and equals to Container breaks move and delete child.setParent(null); childs.remove(child); } public void removeContent(final Content content) { contents.size(); contents.remove(content); } public void setAccessLists(final AccessLists accessLists) { this.accessLists = accessLists; } public void setAliases(final List<ContainerTranslation> containerTranslations) { this.containerTranslations = containerTranslations; } public void setChilds(final Set<Container> childs) { this.childs = childs; } public void setContainerTranslations(final List<ContainerTranslation> containerTranslations) { this.containerTranslations = containerTranslations; } public void setContents(final HashSet<Content> contents) { this.contents = contents; } public void setCreatedOn(final Long createdOn) { this.createdOn = createdOn; } public void setDeletedOn(final Date deletedOn) { this.deletedOn = deletedOn; } @Override public void setId(final Long id) { this.id = id; } public void setLanguage(final I18nLanguage language) { this.language = language; } public void setName(final String name) { this.name = name; } public void setOwner(final Group owner) { this.owner = owner; } public void setParent(final Container parent) { this.parent = parent; } public void setToolName(final String toolName) { this.toolName = toolName; } public void setTypeId(final String typeId) { this.typeId = typeId; } @Override public String toString() { return "Container[(" + getStateTokenEncoded() + "): " + getName() + "]"; } }