/* * PersistentDynamicGroup.java * * Copyright (c) 2013, Instituto Superior Técnico. All rights reserved. * * This file is part of bennu-core. * * bennu-core is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * * bennu-core 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along with bennu-core. If not, see * <http://www.gnu.org/licenses/>. */ package org.fenixedu.bennu.core.domain.groups; import java.util.Collection; import java.util.Optional; import java.util.stream.Stream; import org.fenixedu.bennu.core.domain.BennuGroupIndex; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.groups.DynamicGroup; import org.fenixedu.bennu.core.groups.Group; import org.fenixedu.bennu.core.security.Authenticate; import org.fenixedu.commons.i18n.LocalizedString; import org.joda.time.DateTime; import pt.ist.fenixframework.Atomic; import pt.ist.fenixframework.Atomic.TxMode; import pt.ist.fenixframework.dml.runtime.Relation; import com.google.common.collect.Sets; /** * <p> * Mutable named group. In the group language is referred by {@literal #}name. Keeps history of every change made. * </p> * * <p> * In practice it's a wrapper over an immutable group with versioning over the relation between this and the wrapped group. * </p> * * @see PersistentGroup */ public final class PersistentDynamicGroup extends PersistentDynamicGroup_Base { protected PersistentDynamicGroup() { super(); } protected PersistentDynamicGroup(String name, PersistentGroup group) { this(); setName(name); setCreated(new DateTime()); setCreator(Authenticate.getUser()); setGroup(group); setRootForDynamicGroup(getRoot()); } @Override public Group toGroup() { return DynamicGroup.get(getName()); } @Override public String getName() { //FIXME: remove when the framework enables read-only slots return super.getName(); } @Override public PersistentGroup getGroup() { //FIXME: remove when the framework enables read-only slots return super.getGroup(); } @Override public Stream<User> getMembers() { return getGroup().getMembers(); } @Override public Stream<User> getMembers(DateTime when) { return getGroup(when).getMembers(when); } @Override public boolean isMember(User user) { return getGroup().isMember(user); } @Override public boolean isMember(User user, DateTime when) { return getGroup(when).isMember(user, when); } public PersistentGroup getGroup(DateTime when) { if (when.isAfter(getCreated())) { return getGroup(); } if (getPrevious() != null) { return getPrevious().getGroup(when); } return Group.nobody().toPersistentGroup(); } private void pushHistory() { PersistentDynamicGroup old = new PersistentDynamicGroup(); old.setRoot(null); old.setName(getName()); old.setCreated(getCreated()); old.setCreator(getCreator()); old.setGroup(getGroup()); old.setNext(this); setCreated(new DateTime()); setCreator(Authenticate.getUser()); } public PersistentDynamicGroup rename(String name) { pushHistory(); setName(name); return this; } public PersistentDynamicGroup changeGroup(PersistentGroup overridingGroup) { if (!overridingGroup.equals(getGroup())) { pushHistory(); setGroup(overridingGroup); } return this; } @Override protected void gc() { //Dynamic groups are never garbage collected automatically } public boolean isDeletable() { return GroupGC.emptyCustomRelations(this); } public void delete() { if (getPrevious() != null) { getPrevious().gc(); } super.gc(); } @Override protected Collection<Relation<?, ?>> getContextRelations() { return Sets.newHashSet(getRelationDynamicGroupHistoric(), getRelationPersistentDynamicGroupCreator(), getRelationPersistentDynamicGroups(), getRelationPersistentDynamicGroupWrapper()); } public static Optional<PersistentDynamicGroup> getInstance(final String name) { return BennuGroupIndex.dynamic(name); } @Atomic(mode = TxMode.WRITE) public static PersistentDynamicGroup set(final String name, PersistentGroup overridingGroup) { Optional<PersistentDynamicGroup> persistent = PersistentDynamicGroup.getInstance(name); if (persistent.isPresent()) { return persistent.get().changeGroup(overridingGroup); } else { return new PersistentDynamicGroup(name, overridingGroup); } } @Atomic(mode = TxMode.WRITE) public void changePresentationName(LocalizedString presentationName) { setCustomPresentationName(presentationName); } }