Source code: org/jdaemon/era/AbstractCubeDirectory.java
1 /*
2 * AbstractCubeDirectory.java
3 *
4 * Copyright (C) 2002 Jonathan Essex
5 * This program is distributed under the terms of the Lesser GNU General Public
6 * License (v2 or later) per the included COPYING.txt file, or see www.fsf.org.
7 *
8 * Created on November 26, 2002, 9:33 AM
9 */
10
11 package org.jdaemon.era;
12
13 import org.jdaemon.util.QuickList;
14 import org.jdaemon.util.iterator.CompoundIterator;
15
16 import java.util.Iterator;
17 import java.util.List;
18
19 /** Base implementation for cube directories
20 *
21 * Assumes an index of cubes exists on a given attribute set. Implements getCube and getValues in terms of
22 * abstract operations on this index.
23 *
24 * Note: At some stage this implementation should be extended to handle multiple indexes
25 *
26 * @author Jonathan Essex
27 */
28 public abstract class AbstractCubeDirectory implements CubeDirectory {
29
30 /** Create an AbstractDirectoryPath object.
31 *
32 * @returns an AbstractCubeDirectoryPath object which can be used to specify a set of cubes in this directory
33 */
34 public CubeDirectoryPath getPath() {
35 return new AbstractCubeDirectoryPath();
36 }
37
38
39 /** Recursive implementation of getCube(path)
40 *
41 * Takes the given CubeDirectoryPath and composes a Cube by looking up sub-cubes with getCube(QuickList) and
42 * returning a union of the results
43 *
44 * @param path An AbstractCubeDirectoryPath specifying a set of data
45 * @param attributes QuickList of attributes which remain unbound
46 * @param bound_values Quicklist of atributes which have already been bound
47 * @returns a Cube containing all data specified by <I>path</I>
48 */
49 protected Cube getCube(CubeDirectoryPath path, QuickList attributes, QuickList bound_values) {
50
51 Cube cube = null;
52
53 // if no attibutes remain to be bound, lookup the unique cube defined by the bound values
54 if (attributes == QuickList.EMPTY) {
55 cube = getCube(bound_values);
56 } else {
57 // Get the first attribute that remains to be bound
58 String attr_to_bind = (String)attributes.head();
59 // Get all the values for this attribute stored in the path
60 Iterator values_to_bind = path.getKeyValues(attr_to_bind).iterator();
61 // If no values stored in path, use all values in index which satisfy the attributes already bound
62 if (!values_to_bind.hasNext()) values_to_bind = getKeyValues(bound_values, attr_to_bind);
63 // Now iterate over all the values to bind
64 if (values_to_bind.hasNext()) {
65 // Obtain first cube by recursively invoking this method to bind remaining attributes
66 cube = getCube(path, attributes.tail(), bound_values.add(values_to_bind.next()));
67 // Create result as union of first cube with cubes obtailed for all remaining attribute balues
68 while (values_to_bind.hasNext()) {
69 cube = cube.union(getCube(path, attributes.tail(), bound_values.add(values_to_bind.next())));
70 }
71 }
72 }
73 return cube;
74 }
75
76 /** Get a Cube object for the given directory path.
77 *
78 * Takes the given CubeDirectoryPath and composes a Cube buy looking up sub-cubes with getCube(QuickList) and
79 * creating compound cubes as appropriate. Implemented by the protected method getCube(path, attributes, values).
80 *
81 * @param path An AbstractCubeDirectoryPath specifying a set of data
82 * @returns a Cube containing all data specified by <I>path</I>
83 */
84 public Cube getCube(CubeDirectoryPath path) {
85 return getCube(path, QuickList.EMPTY.add(getKeyAttributes()), QuickList.EMPTY);
86 }
87
88 /** Recursive implementation of getKeyValues(path, attribute)
89 *
90 * Takes the given CubeDirectoryPath and composes an iterator over possible values of the key attribute. An
91 * attempt is made to prune values which are excluded by the constraints in the path.
92 *
93 * @param path An AbstractCubeDirectoryPath specifying a set of data
94 * @param attribute A key attribute for which a listing of possible values is required
95 * @param attributes QuickList of attributes which remain unbound
96 * @param bound_values Quicklist of atributes which have already been bound
97 * @returns a Cube containing all data specified by <I>path</I>
98 */
99 protected Iterator getKeyValues(CubeDirectoryPath path, String attribute, QuickList attributes, QuickList bound_values) {
100
101 String attr_to_bind = (String)attributes.head();
102 Iterator values_to_bind = path.getKeyValues(attr_to_bind).iterator();
103 Iterator result = null;
104
105 // If no values bound in path for attr, list values constrained by attributes so far bound
106 if (!values_to_bind.hasNext())
107 return getKeyValues(bound_values, attr_to_bind);
108 else {
109 result = getKeyValues(path, attribute, attributes.tail(), bound_values.add(values_to_bind.next()));
110
111 while (values_to_bind.hasNext()) {
112 result = new CompoundIterator(result, getKeyValues(path, attribute, attributes.tail(), bound_values.add(values_to_bind.next())));
113 }
114 }
115 return result;
116 }
117
118 /** List all values of the given key attribute contained by this directory
119 *
120 * @param attribute Key attribute for which values will be listed
121 * @returns Iterator over key values of given attribute
122 * @author Jonathan Essex
123 */
124 public Iterator getKeyValues(CubeDirectoryPath path, String attribute) {
125 Iterator result = path.getKeyValues(attribute).iterator();
126 if (result.hasNext()) {
127 return result;
128 } else {
129 return getKeyValues(path, attribute, QuickList.EMPTY.add(getKeyAttributes()), QuickList.EMPTY);
130 }
131 }
132
133 /** Get metadata for the cubes contained by this Directory
134 *
135 * @returns A CubeDescriptor describing the cubes contained by this directory
136 */
137 public abstract CubeDescriptor getCubeDescriptor();
138
139 /** Get an iterator over the key attributes used by this directory
140 *
141 * @return Iterator over all key attributes
142 */
143 public abstract List getKeyAttributes();
144
145 /** List all values of the given key attribute contained by this directory.
146 *
147 * @param attribute Key attribute for which values will be listed
148 * @returns Iterator over key values of given attribute
149 * @author Jonathan Essex
150 */
151 protected abstract Iterator getKeyValues(QuickList bound_values, String attr);
152
153 protected abstract Cube getCube(QuickList bound_values);
154 }