/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. */ package com.liferay.portal.kernel.service.persistence.impl; import com.liferay.portal.kernel.model.NestedSetsTreeNodeModel; import java.util.List; import java.util.Objects; /** * @author Shuyang Zhou */ public abstract class NestedSetsTreeManager<T extends NestedSetsTreeNodeModel> { public long countAncestors(T t) { return doCountAncestors( t.getNestedSetsTreeNodeScopeId(), t.getNestedSetsTreeNodeLeft(), t.getNestedSetsTreeNodeRight()); } public long countDescendants(T t) { return doCountDescendants( t.getNestedSetsTreeNodeScopeId(), t.getNestedSetsTreeNodeLeft(), t.getNestedSetsTreeNodeRight()); } public void delete(T t) { doUpdate( t.getNestedSetsTreeNodeScopeId(), -1, t.getNestedSetsTreeNodeLeft(), false, t.getNestedSetsTreeNodeRight(), false, null); doUpdate( t.getNestedSetsTreeNodeScopeId(), true, -2, t.getNestedSetsTreeNodeRight(), false); doUpdate( t.getNestedSetsTreeNodeScopeId(), false, -2, t.getNestedSetsTreeNodeRight(), false); } public List<T> getAncestors(T t) { return doGetAncestors( t.getNestedSetsTreeNodeScopeId(), t.getNestedSetsTreeNodeLeft(), t.getNestedSetsTreeNodeRight()); } public List<T> getDescendants(T t) { return doGetDescendants( t.getNestedSetsTreeNodeScopeId(), t.getNestedSetsTreeNodeLeft(), t.getNestedSetsTreeNodeRight()); } public void insert(T t, T parentT) { if (parentT == null) { long maxNestedSetsTreeNodeRight = getMaxNestedSetsTreeNodeRight( t.getNestedSetsTreeNodeScopeId()); t.setNestedSetsTreeNodeLeft(maxNestedSetsTreeNodeRight); t.setNestedSetsTreeNodeRight(maxNestedSetsTreeNodeRight + 1); } else { doUpdate( t.getNestedSetsTreeNodeScopeId(), true, 2, parentT.getNestedSetsTreeNodeRight(), true); doUpdate( t.getNestedSetsTreeNodeScopeId(), false, 2, parentT.getNestedSetsTreeNodeRight(), true); t.setNestedSetsTreeNodeLeft(parentT.getNestedSetsTreeNodeRight()); t.setNestedSetsTreeNodeRight( parentT.getNestedSetsTreeNodeRight() + 1); } } public void move(T t, T oldParentT, T newParentT) { if (Objects.equals(oldParentT, newParentT)) { return; } List<T> descendants = doGetDescendants( t.getNestedSetsTreeNodeScopeId(), t.getNestedSetsTreeNodeLeft(), t.getNestedSetsTreeNodeRight()); long newParentNestedSetsTreeNodeRight = 0; if (newParentT == null) { newParentNestedSetsTreeNodeRight = getMaxNestedSetsTreeNodeRight( t.getNestedSetsTreeNodeScopeId()); } else { newParentNestedSetsTreeNodeRight = newParentT.getNestedSetsTreeNodeRight(); } long delta = 0; if (t.getNestedSetsTreeNodeRight() < newParentNestedSetsTreeNodeRight) { doUpdate( t.getNestedSetsTreeNodeScopeId(), -(t.getNestedSetsTreeNodeRight() - t.getNestedSetsTreeNodeLeft() + 1), t.getNestedSetsTreeNodeRight(), false, newParentNestedSetsTreeNodeRight, false, null); delta = newParentNestedSetsTreeNodeRight - t.getNestedSetsTreeNodeRight() - 1; doUpdate( t.getNestedSetsTreeNodeScopeId(), delta, t.getNestedSetsTreeNodeLeft(), true, t.getNestedSetsTreeNodeRight(), true, descendants); } else { doUpdate( t.getNestedSetsTreeNodeScopeId(), t.getNestedSetsTreeNodeRight() - t.getNestedSetsTreeNodeLeft() + 1, newParentNestedSetsTreeNodeRight, true, t.getNestedSetsTreeNodeLeft(), false, null); delta = newParentNestedSetsTreeNodeRight - t.getNestedSetsTreeNodeLeft(); doUpdate( t.getNestedSetsTreeNodeScopeId(), delta, t.getNestedSetsTreeNodeLeft(), true, t.getNestedSetsTreeNodeRight(), true, descendants); } t.setNestedSetsTreeNodeLeft(t.getNestedSetsTreeNodeLeft() + delta); t.setNestedSetsTreeNodeRight(t.getNestedSetsTreeNodeRight() + delta); } protected abstract long doCountAncestors( long nestedSetsTreeNodeScopeId, long nestedSetsTreeNodeLeft, long nestedSetsTreeNodeRight); protected abstract long doCountDescendants( long nestedSetsTreeNodeScopeId, long nestedSetsTreeNodeLeft, long nestedSetsTreeNodeRight); protected abstract List<T> doGetAncestors( long nestedSetsTreeNodeScopeId, long nestedSetsTreeNodeLeft, long nestedSetsTreeNodeRight); protected abstract List<T> doGetDescendants( long nestedSetsTreeNodeScopeId, long nestedSetsTreeNodeLeft, long nestedSetsTreeNodeRight); protected abstract void doUpdate( long nestedSetsTreeNodeScopeId, boolean leftOrRight, long delta, long limit, boolean inclusive); protected abstract void doUpdate( long nestedSetsTreeNodeScopeId, long delta, long start, boolean startInclusive, long end, boolean endInclusive, List<T> includeList); protected abstract long getMaxNestedSetsTreeNodeRight( long nestedSetsTreeNodeScopeId); }