001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2008
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.core.storage;
034:
035: import com.flexive.shared.content.FxPK;
036: import com.flexive.shared.tree.FxTreeMode;
037:
038: import java.io.Serializable;
039: import java.math.BigDecimal;
040: import java.math.RoundingMode;
041:
042: /**
043: * Information about a tree node that implementation specific and provide information about parameters
044: * relevant to the nested set model with spreading.
045: *
046: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
047: * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
048: */
049: public class FxTreeNodeInfoSpreaded extends FxTreeNodeInfo implements
050: Serializable {
051:
052: private static final long serialVersionUID = -2090532401288230681L;
053:
054: private final static BigDecimal THREE = new BigDecimal(3);
055: private BigDecimal innerSpace;
056: private BigDecimal defaultSpacing;
057: private BigDecimal left;
058: private BigDecimal right;
059: private BigDecimal parentLeft;
060: private BigDecimal parentRight;
061: private BigDecimal maxChildRight;
062:
063: /**
064: * Ctor
065: *
066: * @param left left position
067: * @param right right position
068: * @param parentLeft parent left
069: * @param parentRight parent right
070: * @param maxChildRight max. number of children right
071: * @param totalChildCount total number of children
072: * @param directChildCount number of direct children
073: * @param depth depth of this node
074: * @param parentId parent id
075: * @param id node id
076: * @param name name
077: * @param reference referenced content
078: * @param ACLId ACL of the referenced content
079: * @param mode tree mode
080: * @param position position
081: * @param template template
082: * @param modifiedAt last modified at
083: * @param mayEdit edit permission of the referenced ACL
084: * @param mayCreate create permission of the referenced ACL
085: * @param mayDelete delete permission of the referenced ACL
086: * @param mayRelate relate permission of the referenced ACL
087: * @param mayExport export permission of the referenced ACL
088: */
089: public FxTreeNodeInfoSpreaded(BigDecimal left, BigDecimal right,
090: BigDecimal parentLeft, BigDecimal parentRight,
091: BigDecimal maxChildRight, int totalChildCount,
092: int directChildCount, int depth, long parentId, long id,
093: String name, FxPK reference, long ACLId, FxTreeMode mode,
094: int position, String template, long modifiedAt,
095: boolean mayEdit, boolean mayCreate, boolean mayDelete,
096: boolean mayRelate, boolean mayExport) {
097: super (totalChildCount, directChildCount, depth, parentId, id,
098: name, reference, ACLId, mode, position, template,
099: modifiedAt, mayEdit, mayDelete, mayRelate, mayExport,
100: mayCreate);
101: this .left = left;
102: this .right = right;
103: this .parentLeft = parentLeft;
104: this .parentRight = parentRight;
105: this .maxChildRight = maxChildRight;
106: // Compute the space between the node left and right border
107: innerSpace = (right.subtract(left)).subtract(BigDecimal.ONE);
108: // Compute the default spacing between borders inside this node
109: defaultSpacing = getSpacing(totalChildCount);
110: }
111:
112: /**
113: * Get the inner space (space between left and right border)
114: *
115: * @return inner space
116: */
117: public BigDecimal getInnerSpace() {
118: return innerSpace;
119: }
120:
121: /**
122: * Get the default spacing.
123: *
124: * @return default spacing
125: */
126: public BigDecimal getDefaultSpacing() {
127: return defaultSpacing;
128: }
129:
130: /**
131: * Get the left position
132: *
133: * @return left position
134: */
135: @Override
136: public BigDecimal getLeft() {
137: return left;
138: }
139:
140: /**
141: * Get the right position
142: *
143: * @return right position
144: */
145: @Override
146: public BigDecimal getRight() {
147: return right;
148: }
149:
150: /**
151: * Get the parent left position
152: *
153: * @return parent left position
154: */
155: @Override
156: public BigDecimal getParentLeft() {
157: return parentLeft;
158: }
159:
160: /**
161: * Get the parent right position
162: *
163: * @return parent right position
164: */
165: @Override
166: public BigDecimal getParentRight() {
167: return parentRight;
168: }
169:
170: /**
171: * The maximum rgt value of all childs of the node, or if no child exists the rgt of
172: * the node itself.
173: * <p/>
174: * Null if no childs are present.
175: *
176: * @return The maximum rgt value of all childs of the node
177: */
178: public BigDecimal getMaxChildRight() {
179: if (directChildCount == 0 || maxChildRight == null) {
180: return right;
181: } else {
182: return maxChildRight;
183: }
184: }
185:
186: /**
187: * Get the spacing needed to hold requested number of children
188: *
189: * @param childCount number of children to get the spacing for
190: * @return spacing
191: */
192: public BigDecimal getSpacing(int childCount) {
193: // Every node needs 2 positions for its lft and rgt borders
194: BigDecimal result = innerSpace.subtract(new BigDecimal(
195: childCount * 2));
196: // Compute the spaces needed in and between the nodes
197: BigDecimal spacesNeeded = new BigDecimal((childCount * 2) + 1);
198: // Devide the space available and floor it
199: return result.divide(spacesNeeded, RoundingMode.FLOOR);
200: }
201:
202: /**
203: * Returns true if the spaces used within the node and its children can be optimized.
204: *
205: * @return true if the spaces used within the node and its children can be optimized
206: */
207: public boolean isSpaceOptimizable() {
208: // defaultSpacing > 3
209: return defaultSpacing.compareTo(THREE) == 1;
210: }
211:
212: /**
213: * Returns true if the node can hold the given amount of children between its left and right
214: * borders without the parent(s) being reorganized.
215: *
216: * @param childCount the child count to check for
217: * @param spacing the spacing between the nodes
218: * @return true if the node can hold the given amount of children without beeing reorganized
219: */
220: public boolean hasSpaceFor(int childCount, int spacing) {
221: // Every child node needs at least 2 positions (the left and right border)
222: BigDecimal spaceNeeded = new BigDecimal(childCount * 2);
223: // Compute needed spacing
224: BigDecimal totalSpacing = spacing <= 0 ? BigDecimal.ZERO
225: : new BigDecimal(((childCount * 2) + 1) * spacing);
226: // See if we can fit them all in
227: spaceNeeded = spaceNeeded.add(totalSpacing);
228: return ((this .getInnerSpace().subtract(spaceNeeded))
229: .compareTo(BigDecimal.ZERO) > 0);
230: }
231:
232: /**
233: * Is this node capable of holding <code>childCount</code> child nodes?
234: *
235: * @param childCount number of childnodes this node should be able to hold
236: * @return if there is enough space to hold <code>childCount</code> child nodes
237: */
238: public boolean hasSpaceFor(int childCount) {
239: return getSpacing(childCount).compareTo(BigDecimal.ZERO) >= 0;
240: }
241:
242: /**
243: * {@inheritDoc}
244: */
245: @Override
246: public boolean isParentOf(FxTreeNodeInfo node) {
247: if (node instanceof FxTreeNodeInfoSpreaded)
248: return this .getLeft().compareTo(
249: ((FxTreeNodeInfoSpreaded) node).getLeft()) < 0
250: && this .getRight().compareTo(
251: ((FxTreeNodeInfoSpreaded) node).getRight()) > 0;
252: else
253: return node.getLeft().longValue() < getLeft().longValue()
254: && node.getRight().longValue() > getRight()
255: .longValue();
256: }
257: }
|