001    /*
002    // $Id: //open/mondrian/src/main/mondrian/rolap/agg/AbstractColumnPredicate.java#6 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2004-2005 TONBELLER AG
007    // Copyright (C) 2006-2008 Julian Hyde and others
008    // All Rights Reserved.
009    // You must accept the terms of that agreement to use this software.
010    */
011    package mondrian.rolap.agg;
012    
013    import mondrian.rolap.StarColumnPredicate;
014    import mondrian.rolap.RolapStar;
015    import mondrian.rolap.StarPredicate;
016    import mondrian.rolap.sql.SqlQuery;
017    import mondrian.rolap.BitKey;
018    import mondrian.olap.Util;
019    
020    import java.util.List;
021    import java.util.Collections;
022    import java.util.ArrayList;
023    
024    /**
025     * A <code>AbstractColumnPredicate</code> is an abstract implementation for
026     * {@link mondrian.rolap.StarColumnPredicate}.
027     *
028     * @version $Id: //open/mondrian/src/main/mondrian/rolap/agg/AbstractColumnPredicate.java#6 $
029     */
030    public abstract class AbstractColumnPredicate implements StarColumnPredicate {
031        protected final RolapStar.Column constrainedColumn;
032        private final BitKey constrainedColumnBitKey;
033    
034        /**
035         * Creates an AbstractColumnPredicate.
036         *
037         * @param constrainedColumn Constrained column
038         */
039        protected AbstractColumnPredicate(RolapStar.Column constrainedColumn) {
040            this.constrainedColumn = constrainedColumn;
041            /*
042             * Check if contraintedColumns are null.
043             * (Example: FastBatchingCellReader.testAggregateDistinctCount5()).
044             */
045            if (constrainedColumn != null && constrainedColumn.getTable() != null) {
046                constrainedColumnBitKey =
047                    BitKey.Factory.makeBitKey(
048                        constrainedColumn.getStar().getColumnCount());
049                constrainedColumnBitKey.clear();
050                constrainedColumnBitKey.set(constrainedColumn.getBitPosition());
051            } else {
052                constrainedColumnBitKey = null;
053            }
054        }
055    
056        public String toString() {
057            final StringBuilder buf = new StringBuilder();
058            buf.append(constrainedColumn.getExpression().getGenericExpression());
059            describe(buf);
060            return buf.toString();
061        }
062    
063        public RolapStar.Column getConstrainedColumn() {
064            return constrainedColumn;
065        }
066    
067        public List<RolapStar.Column> getConstrainedColumnList() {
068            return Collections.singletonList(constrainedColumn);
069        }
070    
071        public BitKey getConstrainedColumnBitKey() {
072            return constrainedColumnBitKey;
073        }
074    
075        public boolean evaluate(List<Object> valueList) {
076            assert valueList.size() == 1;
077            return evaluate(valueList.get(0));
078        }
079    
080        public boolean equalConstraint(StarPredicate that) {
081            return false;
082        }
083    
084        public StarPredicate or(StarPredicate predicate) {
085            if (predicate instanceof StarColumnPredicate) {
086                StarColumnPredicate starColumnPredicate =
087                    (StarColumnPredicate) predicate;
088                if (starColumnPredicate.getConstrainedColumn() ==
089                    getConstrainedColumn()) {
090                    return orColumn(starColumnPredicate);
091                }
092            }
093            final List<StarPredicate> list = new ArrayList<StarPredicate>(2);
094            list.add(this);
095            list.add(predicate);
096            return new OrPredicate(list);
097        }
098    
099        public StarColumnPredicate orColumn(StarColumnPredicate predicate) {
100            assert predicate.getConstrainedColumn() == getConstrainedColumn();
101            if (predicate instanceof ListColumnPredicate) {
102                ListColumnPredicate that = (ListColumnPredicate) predicate;
103                final List<StarColumnPredicate> list =
104                    new ArrayList<StarColumnPredicate>();
105                list.add(this);
106                list.addAll(that.getPredicates());
107                return new ListColumnPredicate(
108                    getConstrainedColumn(),
109                    list);
110            } else {
111                final List<StarColumnPredicate> list =
112                    new ArrayList<StarColumnPredicate>(2);
113                list.add(this);
114                list.add(predicate);
115                return new ListColumnPredicate(
116                    getConstrainedColumn(),
117                    list);
118            }
119        }
120    
121        public StarPredicate and(StarPredicate predicate) {
122            final List<StarPredicate> list = new ArrayList<StarPredicate>(2);
123            list.add(this);
124            list.add(predicate);
125            return new AndPredicate(list);
126        }
127    
128        public void toSql(SqlQuery sqlQuery, StringBuilder buf) {
129            throw Util.needToImplement(this);
130        }
131    
132        protected static List<StarColumnPredicate> cloneListWithColumn(
133            RolapStar.Column column,
134            List<StarColumnPredicate> list)
135        {
136            List<StarColumnPredicate> newList =
137                new ArrayList<StarColumnPredicate>(list.size());
138            for (StarColumnPredicate predicate : list) {
139                newList.add(predicate.cloneWithColumn(column));
140            }
141            return newList;
142        }
143    
144        /**
145         * Factory for {@link mondrian.rolap.StarPredicate}s and
146         * {@link mondrian.rolap.StarColumnPredicate}s.
147         */
148        public static class Factory {
149            /**
150             * Returns a predicate which tests whether the column's
151             * value is equal to a given constant.
152             *
153             * @param column Constrained column
154             * @param value Value
155             * @return Predicate which tests whether the column's value is equal
156             *   to a column constraint's value
157             */
158            public static StarColumnPredicate equal(
159                RolapStar.Column column,
160                Object value)
161            {
162                return new ValueColumnPredicate(column, value);
163            }
164    
165            /**
166             * Returns predicate which is the OR of a list of predicates.
167             *
168             * @param column Column being constrained
169             * @param list List of predicates
170             * @return Predicate which is an OR of the list of predicates
171             */
172            public static StarColumnPredicate or(
173                RolapStar.Column column,
174                List<StarColumnPredicate> list)
175            {
176                return new ListColumnPredicate(column, list);
177            }
178    
179            /**
180             * Returns a predicate which always evaluates to TRUE or FALSE.
181             * @param b Truth value
182             * @return Predicate which always evaluates to truth value
183             */
184            public static LiteralStarPredicate bool(boolean b) {
185                return b ? LiteralStarPredicate.TRUE : LiteralStarPredicate.FALSE;
186            }
187    
188            /**
189             * Returns a predicate which tests whether the column's
190             * value is equal to column predicate's value.
191             *
192             * @param predicate Column predicate
193             * @return Predicate which tests whether the column's value is equal
194             *   to a column predicate's value
195             */
196            public static StarColumnPredicate equal(ValueColumnPredicate predicate) {
197                return equal(
198                    predicate.getConstrainedColumn(),
199                    predicate.getValue());
200            }
201        }
202    }
203    
204    // End AbstractColumnPredicate.java