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.FxLanguage;
036: import com.flexive.shared.content.FxPK;
037: import com.flexive.shared.exceptions.FxApplicationException;
038: import com.flexive.shared.exceptions.FxTreeException;
039: import com.flexive.shared.interfaces.ContentEngine;
040: import com.flexive.shared.interfaces.SequencerEngine;
041: import com.flexive.shared.tree.FxTreeMode;
042: import com.flexive.shared.tree.FxTreeNode;
043: import com.flexive.shared.value.FxString;
044:
045: import java.sql.Connection;
046: import java.util.List;
047:
048: /**
049: * Tree storage interface.
050: * The tree used is an enhanced nested set model tree based on the article found at
051: * http://dev.mysql.com/tech-resources/articles/hierarchical-data.html enhanced by using spacing
052: * for performance, and adds the parent and depth columns to even more simplify queries.
053: * Nested Set Models are optimized for read/query operations, but slow on update/move/create operations. This
054: * implementation uses "spacing" between nodes to minimize slow operations - only when a level runs out of "space" a
055: * reorganization on a part of the tree is performed (this can take quite a few seconds, dependong on the amount of
056: * affected nodes), otherwise the update operation will be almost as fast as when using a standard Adjacency List Model
057: * (pure id<->parent based) tree.
058: * Since count(*) can be very slow the total childcount of every node is stored within its row.
059: *
060: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
061: * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
062: */
063: public interface TreeStorage {
064:
065: public final static long ROOT_NODE = 1;
066:
067: /**
068: * Get various information about a tree node
069: *
070: * @param con an open and valid connection
071: * @param mode Live or Edit mode
072: * @param nodeId id of the node to examine
073: * @return FxTreeNodeInfo
074: * @throws FxApplicationException on errors
075: */
076: FxTreeNodeInfo getTreeNodeInfo(Connection con, FxTreeMode mode,
077: long nodeId) throws FxApplicationException;
078:
079: /**
080: * Create a new node
081: *
082: * @param con an open and valid Connection
083: * @param seq reference to the sequencer
084: * @param ce reference to the content engine
085: * @param mode tree mode
086: * @param nodeId use this id unless it is < 0 then generate a new one
087: * @param parentNodeId id of the parent node
088: * @param name name (will only be used if no FQN property is available in the reference)
089: * @param label label for Caption property (only used if new reference is created)
090: * @param position position
091: * @param reference referenced content id
092: * @param template optional template to assign @return id of the created node
093: * @return id of the node created
094: * @throws FxApplicationException on errors
095: */
096: long createNode(Connection con, SequencerEngine seq,
097: ContentEngine ce, FxTreeMode mode, long nodeId,
098: long parentNodeId, String name, FxString label,
099: int position, FxPK reference, String template)
100: throws FxApplicationException;
101:
102: /**
103: * Create a set of nodes and attach new Folder instances to them
104: *
105: * @param con an open and valid connection
106: * @param seq reference to the sequencer
107: * @param ce reference to the content engine
108: * @param mode tree mode
109: * @param parentNodeId id of the parent node
110: * @param path the path to create (separated by "/")
111: * @param position position within each fqn
112: * @return array of the id's
113: * @throws FxApplicationException on errors
114: */
115: long[] createNodes(Connection con, SequencerEngine seq,
116: ContentEngine ce, FxTreeMode mode, long parentNodeId,
117: String path, int position) throws FxApplicationException;
118:
119: /**
120: * Removes all tree entries and creates new root nodes
121: *
122: * @param con an open and valid Connection
123: * @param ce ContentEngine reference to create a new folder
124: * @param mode the tree to operate on
125: * @throws FxApplicationException on errors
126: */
127: void clearTree(Connection con, ContentEngine ce, FxTreeMode mode)
128: throws FxApplicationException;
129:
130: /**
131: * Get the id of rightmost node in a path described by the nodes FQNs
132: *
133: * @param con an open and valid connection
134: * @param mode tree mode
135: * @param startNode the start node id
136: * @param path requested path consisting of FQNs
137: * @return id of the rightmost node in the path
138: * @throws FxApplicationException on errors
139: */
140: long getIdByFQNPath(Connection con, FxTreeMode mode,
141: long startNode, String path) throws FxApplicationException;
142:
143: /**
144: * Get the id of rightmost node in a path described by the nodes Labels/Captions
145: *
146: * @param con an open and valid connection
147: * @param mode tree mode
148: * @param startNode the start node id
149: * @param path requested path consisting of Labels/Captions
150: * @return id of the rightmost node in the path
151: * @throws FxApplicationException on errors
152: */
153: long getIdByLabelPath(Connection con, FxTreeMode mode,
154: long startNode, String path) throws FxApplicationException;
155:
156: /**
157: * Load a single node (without and childnodes!)
158: *
159: * @param con an open and valid connection
160: * @param mode tree mode
161: * @param nodeId node id
162: * @return node without any preloaded or chained children
163: * @throws FxApplicationException on errors
164: */
165: FxTreeNode getNode(Connection con, FxTreeMode mode, long nodeId)
166: throws FxApplicationException;
167:
168: /**
169: * Load a (sub)tree.
170: * Loading a tree with all data takes a lot of time!
171: * If <code>loadPartial</code> is set to <code>true</code> the position and path of the nodes is not initialized and
172: * the labels are only loaded in the language requested with <code>partialLoadLanguage</code>.
173: * Incase the position, path or (detailed) label is needed the node can be reloaded using <code>getNode()</code>
174: *
175: * @param con an open and valid connection
176: * @param ce reference to ContentEngine
177: * @param mode tree mode
178: * @param nodeId start node id
179: * @param depth depth to load
180: * @param loadPartial load all data?
181: * @param partialLoadLanguage language to load for labels if not loading fully
182: * @return start node with preloaded and chained children
183: * @throws FxApplicationException on errors
184: */
185: FxTreeNode getTree(Connection con, ContentEngine ce,
186: FxTreeMode mode, long nodeId, int depth,
187: boolean loadPartial, FxLanguage partialLoadLanguage)
188: throws FxApplicationException;
189:
190: /**
191: * Returns the path for a specified id.
192: *
193: * @param con an open and valid connection
194: * @param mode tree mode
195: * @param id the id to get the path for
196: * @return the path for the requested id
197: * @throws FxApplicationException on errors
198: */
199: String getPathById(Connection con, FxTreeMode mode, long id)
200: throws FxApplicationException;
201:
202: /**
203: * Check if a node with the requested id exists
204: *
205: * @param con an open and valid Connection
206: * @param mode tree mode
207: * @param id node id to check
208: * @return if a node with the requested id exists
209: * @throws FxApplicationException on errors
210: */
211: boolean exists(Connection con, FxTreeMode mode, long id)
212: throws FxApplicationException;
213:
214: /**
215: * Callback from the ContentEngine (actually the HierarchicalStorage implementation) if aFQN
216: * property has changed to reflect changes back into the tree
217: *
218: * @param con an open and valid connection
219: * @param referenceId id of the referenced content
220: * @param maxVersion change affects the max version?
221: * @param liveVersion change affects the live version
222: * @param name the new name
223: * @throws FxApplicationException on errors
224: */
225: void syncFQNName(Connection con, long referenceId,
226: boolean maxVersion, boolean liveVersion, String name)
227: throws FxApplicationException;
228:
229: /**
230: * Update the name of a tree node.
231: * Will update the FQN of the referenced content as well if assigned.
232: *
233: * @param con an open and valid connection
234: * @param mode tree mode
235: * @param ce reference to the content engine
236: * @param nodeId node id to update
237: * @param name new name
238: * @throws FxApplicationException on errors
239: */
240: void updateName(Connection con, FxTreeMode mode, ContentEngine ce,
241: long nodeId, String name) throws FxApplicationException;
242:
243: /**
244: * Returns a list of paths made up of Caption's for the given id's.
245: * If there is no caption propery found in the instance, the FQN will be used.
246: * The root node will be excluded.
247: * <p/>
248: * Example: input ids = [12,4]<br>
249: * Result: ["/DescriptionForNode1/DescriptionForNode12","/DescriptionForNode1/DescriptionForNode4"]
250: *
251: * @param con an open and valid connection
252: * @param mode tree mode to use (Live or Edit tree)
253: * @param labelPropertyId propertyId of the label
254: * @param language desired result language
255: * @param stripNodeInfos remove node specific meta information in result
256: * @param nodeIds the id's of the nodes to get the path to the root node for
257: * @return a list with all paths made up of Caption's
258: * @throws FxApplicationException on errors
259: */
260: List<String> getLabels(Connection con, FxTreeMode mode,
261: long labelPropertyId, FxLanguage language,
262: boolean stripNodeInfos, long... nodeIds)
263: throws FxApplicationException;
264:
265: /**
266: * Moves a node to the specified parent and the specified position.
267: *
268: * @param con an open and valid connection
269: * @param seq reference to the sequencer
270: * @param mode tree mode
271: * @param nodeId the node to move
272: * @param newParentId the new parent
273: * @param newPosition the new position in the new parents children, 0 based
274: * @throws FxApplicationException on errors
275: */
276: void move(Connection con, SequencerEngine seq, FxTreeMode mode,
277: long nodeId, long newParentId, int newPosition)
278: throws FxApplicationException;
279:
280: /**
281: * Remove a node
282: *
283: * @param con an open and valid connection
284: * @param mode tree mode
285: * @param ce reference to the content engine
286: * @param nodeId the node to remove
287: * @param removeChildren if true all nodes that are inside the subtree of the given node are
288: * deleted as well, if false the subtree is moved one level up (to the parent of the specified
289: * node)
290: * @throws FxApplicationException on errors
291: */
292: void removeNode(Connection con, FxTreeMode mode, ContentEngine ce,
293: long nodeId, boolean removeChildren)
294: throws FxApplicationException;
295:
296: /**
297: * Returns all ids from the given node up to the root.
298: *
299: * @param con an open and valid connection
300: * @param mode tree mode
301: * @param nodeId the node id to start with
302: * @return all ids from the given node up to the root or null if the node was not found
303: * @throws FxApplicationException on errors
304: */
305: long[] getIdChain(Connection con, FxTreeMode mode, long nodeId)
306: throws FxApplicationException;
307:
308: /**
309: * Sets the template of the node.
310: *
311: * @param con an open and valid connection
312: * @param mode tree mode
313: * @param nodeId the node id
314: * @param template the tamplate, or null for no template
315: * @throws FxApplicationException on errors
316: */
317: void setTemplate(Connection con, FxTreeMode mode, long nodeId,
318: String template) throws FxApplicationException;
319:
320: /**
321: * Activate a single node (and all its parents if necessary)
322: *
323: * @param con an open and valid connections
324: * @param seq reference to the sequencer
325: * @param ce reference to the content engine
326: * @param mode tree mode
327: * @param nodeId id of the node to activate
328: * @throws FxApplicationException on errors
329: */
330: void activateNode(Connection con, SequencerEngine seq,
331: ContentEngine ce, FxTreeMode mode, long nodeId)
332: throws FxApplicationException;
333:
334: /**
335: * Activate a node, its subtree and its parents up to the root node
336: *
337: * @param con an open and valid connection
338: * @param seq reference to the sequencer
339: * @param ce reference to the content engine
340: * @param mode tree mode
341: * @param nodeId node id
342: * @throws FxApplicationException on errors
343: */
344: void activateSubtree(Connection con, SequencerEngine seq,
345: ContentEngine ce, FxTreeMode mode, long nodeId)
346: throws FxApplicationException;
347:
348: /**
349: * Activate all nodes in a tree
350: *
351: * @param con an open and valid connection
352: * @param mode tree mode
353: * @throws com.flexive.shared.exceptions.FxTreeException
354: * on errors
355: */
356: void activateAll(Connection con, FxTreeMode mode)
357: throws FxTreeException;
358:
359: /**
360: * Copy a node and all its children to a new parent node
361: *
362: * @param con an open and valid connection
363: * @param seq reference to the sequencer
364: * @param mode tree mode
365: * @param srcNodeId source node id
366: * @param dstParentNodeId destination parent node id
367: * @param dstPosition destination position
368: * @param deepReferenceCopy perform a deep reference copy, cloning all references
369: * @param copyOfPrefix prefix to set for FQN if deep reference copy is performed
370: * @return id of the copied (new) tree node
371: * @throws com.flexive.shared.exceptions.FxApplicationException
372: * on errors
373: */
374: long copy(Connection con, SequencerEngine seq, FxTreeMode mode,
375: long srcNodeId, long dstParentNodeId, int dstPosition,
376: boolean deepReferenceCopy, String copyOfPrefix)
377: throws FxApplicationException;
378:
379: /**
380: * Get a list of all nodes that are referencing a requested content id
381: *
382: * @param con an open and valid connection
383: * @param mode tree mode
384: * @param referenceId the referenced content id
385: * @return list of all nodes that are referencing a requested content id
386: * @throws com.flexive.shared.exceptions.FxApplicationException
387: * on errors
388: */
389: List<FxTreeNode> getNodesWithReference(Connection con,
390: FxTreeMode mode, long referenceId)
391: throws FxApplicationException;
392:
393: /**
394: * Populate the tree with test data.
395: * This function takes quite some time to complete
396: *
397: * @param con an open and valid connection
398: * @param seq reference to the sequencer
399: * @param ce reference to the content engine
400: * @param mode tree mode
401: * @throws FxApplicationException on errors
402: */
403: void populate(Connection con, SequencerEngine seq,
404: ContentEngine ce, FxTreeMode mode)
405: throws FxApplicationException;
406:
407: /**
408: * Callback when a content is removed to replace it with a folder or remove the node(s)
409: *
410: * @param con an open and valid connection
411: * @param contentId referenced content id
412: * @param liveVersionRemovedOnly if just the live version was removed (other versions have no impact) @throws FxApplicationException on errors
413: * @throws FxApplicationException on errors
414: */
415: void contentRemoved(Connection con, long contentId,
416: boolean liveVersionRemovedOnly)
417: throws FxApplicationException;
418:
419: /**
420: * Perform a complete check on the given tree if checks are enabled
421: *
422: * @param con an open and valid connection
423: * @param mode the tree to check
424: * @throws com.flexive.shared.exceptions.FxApplicationException
425: * on errors
426: */
427: void checkTreeIfEnabled(Connection con, FxTreeMode mode)
428: throws FxApplicationException;
429: }
|