KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > data > containers > ContainerChainedFilter


1 package org.jahia.data.containers;
2
3 import java.util.BitSet JavaDoc;
4
5 import org.jahia.exceptions.JahiaException;
6
7 /**
8  *
9  */

10 public class ContainerChainedFilter implements ContainerFilterInterface
11 {
12
13     private static org.apache.log4j.Logger logger =
14             org.apache.log4j.Logger.getLogger (ContainerChainedFilter.class);
15
16     /**
17      * {@link BitSet#or}.
18      */

19     public static final int OR = 0;
20
21     /**
22      * {@link BitSet#and}.
23      */

24     public static final int AND = 1;
25
26     /**
27      * {@link BitSet#andNot}.
28      */

29     public static final int ANDNOT = 2;
30
31     /**
32      * {@link BitSet#xor}.
33      */

34     public static final int XOR = 3;
35
36     /**
37      * Logical operation when none is declared. Defaults to
38      * {@link BitSet#or}.
39      */

40     public static int DEFAULT = OR;
41
42     /** The filter chain */
43     private ContainerFilterInterface[] chain = null;
44
45     private int[] logicArray;
46
47     private int logic = -1;
48
49     /**
50      * Ctor.
51      * @param chain The chain of filters
52      */

53     public ContainerChainedFilter(ContainerFilterInterface[] chain)
54     {
55         this.chain = chain;
56     }
57
58     /**
59      * Ctor.
60      * @param chain The chain of filters
61      * @param logicArray Logical operations to apply between filters
62      */

63     public ContainerChainedFilter(ContainerFilterInterface[] chain, int[] logicArray)
64     {
65         this.chain = chain;
66         this.logicArray = logicArray;
67     }
68
69     /**
70      * Ctor.
71      * @param chain The chain of filters
72      * @param logic Logicial operation to apply to ALL filters
73      */

74     public ContainerChainedFilter(ContainerFilterInterface[] chain, int logic)
75     {
76         this.chain = chain;
77         this.logic = logic;
78     }
79
80
81
82     //--------------------------------------------------------------------------
83
/**
84      * Perform filtering.
85      * The expected result is a bit set of matching container ids.
86      *
87      * @ param int ctnListID, the container list id
88      * @ return BitSet bitsFromLogic, the expected result as a bit set of matching ctn ids,each bit position set to true correspond to matching ctn ids.
89      */

90     public BitSet JavaDoc doFilter(int ctnListID)
91     throws JahiaException {
92         return this.bits(new FilterData(ctnListID));
93     }
94
95     //--------------------------------------------------------------------------
96
/**
97      * Return the select statement, build with the clauses for all container list of the site.
98      *
99      * @ param int ctnListID, the container list id
100      * @ return String , the sql statement. Null on error
101      */

102     public String JavaDoc getSelect(int ctnListID) {
103         if ( chain == null ){
104             return "";
105         }
106         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
107         FilterData data = new FilterData(ctnListID);
108         ContainerFilterInterface filter = null;
109         String JavaDoc val = "";
110         for ( int i=0; i<chain.length; i++ ){
111             filter = chain[i];
112             val = filter.getSelect(ctnListID);
113             if ( val != null ){
114                 if (i > 0) {
115                     int logop = (this.logic != -1) ? this.logic :
116                                 this.logicArray[i-1];
117                     switch (logop) {
118                         case OR:
119                             buff.append(" UNION ");
120                             break;
121                         case AND:
122                             buff.append(" INTERSECT ");
123                             break;
124                         case XOR:
125                             buff.append(" XOR "); //probably not supported in SQL but this SQL statement is not executed anyway, just used as ID for caching
126
break;
127                         case ANDNOT:
128                             buff.append(" ANDNOT "); //probably not supported in SQL but this SQL statement is not executed anyway, just used as ID for caching
129
break;
130                         default:
131                             buff.append(" DEFAULT_OPERATOR ");//probably not supported in SQL but this SQL statement is not executed anyway, just used as ID for caching
132
break;
133                     }
134                 }
135
136                 buff.append(val);
137             }
138         }
139         return buff.toString();
140     }
141
142     //--------------------------------------------------------------------------
143
/**
144      * Set reference to a containerFilters
145      *
146      * @ return
147      * @ throws JahiaException
148      */

149     public void setContainerFilters(ContainerFilters containerFilters){
150         if ( chain == null ){
151             return;
152         }
153         ContainerFilterInterface filter = null;
154         for ( int i=0; i<chain.length; i++ ){
155             filter = chain[i];
156             filter.setContainerFilters(containerFilters);
157         }
158     }
159
160     //--------------------------------------------------------------------------
161
/**
162      * Perform filtering on a given site or all sites
163      *
164      * The expected result is a bit set of matching container ids.
165      *
166      * If siteId = -1 , returns results from all sites
167      *
168      * If the containerDefinitionName is null, return result from all containers
169      * no regards to it definition !
170      *
171      * @param siteId
172      * @param containerDefinitionName
173      * @param listId , optionally, a listID can be passed to returns all containers of this containerlist.
174      * @return BitSet bitsFromLogic, the expected result as a bit set of matching ctn ids,each bit position set to true correspond to matching ctn ids.
175      * @throws JahiaException
176      */

177     public BitSet JavaDoc doFilterBySite(int siteId, String JavaDoc containerDefinitionName, int listId)
178     throws JahiaException{
179         return this.bits(new FilterData(siteId, containerDefinitionName, listId));
180     }
181
182     //--------------------------------------------------------------------------
183
/**
184      * Return the select statement, build with the clauses for a given site.
185      * If siteId = -1 -> build query for all sites
186      *
187      * If the containerDefinitionName is null, return result from all containers
188      * no regards to it definition !
189      *
190      * @param siteId
191      * @param containerDefinitionName
192      * @return
193      */

194     public String JavaDoc getSelectBySiteID(int siteId,
195             String JavaDoc containerDefinitionName) {
196         if ( chain == null ){
197             return "";
198         }
199         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
200         ContainerFilterInterface filter = null;
201         String JavaDoc val = "";
202         for ( int i=0; i<chain.length; i++ ){
203             filter = chain[i];
204             val = filter.getSelectBySiteID(siteId,containerDefinitionName);
205             if ( val != null ){
206                 if (i > 0) {
207                     int logop = (this.logic != -1) ? this.logic :
208                                 this.logicArray[i-1];
209                     switch (logop) {
210                         case OR:
211                             buff.append(" UNION ");
212                             break;
213                         case AND:
214                             buff.append(" INTERSECT ");
215                             break;
216                         case XOR:
217                             buff.append(" XOR "); //probably not supported in SQL but this SQL statement is not executed anyway, just used as ID for caching
218
break;
219                         case ANDNOT:
220                             buff.append(" ANDNOT ");//probably not supported in SQL but this SQL statement is not executed anyway, just used as ID for caching
221
break;
222                         default:
223                             buff.append(" DEFAULT_OPERATOR ");//probably not supported in SQL but this SQL statement is not executed anyway, just used as ID for caching
224
break;
225                     }
226                 }
227                 buff.append(val);
228             }
229         }
230         return buff.toString();
231     }
232
233     private BitSet JavaDoc bits(FilterData filterData) throws JahiaException
234     {
235         if (logic != -1)
236             return bitsFromLogic(logic, filterData);
237         else if (logicArray != null)
238             return bits(logicArray, filterData);
239         else
240             return bitsFromLogic(DEFAULT, filterData);
241     }
242
243     /**
244      * Delegates to each filter in the chain.
245      * @param logic Logical operation
246      * @return BitSet
247      */

248     private BitSet JavaDoc bitsFromLogic(int logic, FilterData filterData) throws JahiaException
249     {
250         BitSet JavaDoc result;
251         int i = 0;
252
253         /**
254          * First AND operation takes place against a completely false
255          * bitset and will always return zero results. Thanks to
256          * Daniel Armbrust for pointing this out and suggesting workaround.
257          */

258         if (logic == AND)
259         {
260             if ( !filterData.isSiteSearch() ) {
261                 result = (BitSet JavaDoc) chain[i].doFilter(filterData.getListId()).clone();
262             } else {
263                 result = (BitSet JavaDoc) chain[i].doFilterBySite(filterData.getSiteId(),
264                         filterData.getContainerDefinitionName(),filterData.getListId()).clone();
265             }
266             ++i;
267         }
268         else
269         {
270             result = new BitSet JavaDoc();
271         }
272
273         for (; i < chain.length; i++)
274         {
275             doChain(result, logic, chain[i], filterData);
276         }
277         return result;
278     }
279
280     /**
281      * Delegates to each filter in the chain.
282      * @param logic Logical operation
283      * @return BitSet
284      */

285     private BitSet JavaDoc bits(int[] logic, FilterData filterData) throws JahiaException
286     {
287         if (logic.length < chain.length-1)
288             throw new IllegalArgumentException JavaDoc("Invalid number of elements in logic array");
289
290         BitSet JavaDoc result = null;
291         if ( !filterData.isSiteSearch() ) {
292             result = (BitSet JavaDoc) chain[0].doFilter(filterData.getListId()).clone();
293         } else {
294             result = (BitSet JavaDoc) chain[0].doFilterBySite(filterData.getSiteId(),
295                     filterData.getContainerDefinitionName(),filterData.getListId()).clone();
296         }
297
298         for (int i=1; i < chain.length; i++)
299         {
300             doChain(result, logic[i-1], chain[i], filterData);
301         }
302         return result;
303     }
304
305     private void doChain(BitSet JavaDoc result, int logic, ContainerFilterInterface filter, FilterData filterData)
306     throws JahiaException
307     {
308         switch (logic)
309         {
310             case OR:
311                 if ( !filterData.isSiteSearch() ) {
312                     result.or(filter.doFilter(filterData.getListId()));
313                 } else {
314                     result.or(filter.doFilterBySite(filterData.getSiteId(),
315                             filterData.getContainerDefinitionName(),filterData.getListId()));
316                 }
317                 break;
318             case AND:
319                 if (result.isEmpty()) // --> no need to execute next filter
320
break;
321                 if ( !filterData.isSiteSearch() ) {
322                     result.and(filter.doFilter(filterData.getListId()));
323                 } else {
324                     result.and(filter.doFilterBySite(filterData.getSiteId(),
325                             filterData.getContainerDefinitionName(),filterData.getListId()));
326                 }
327                 break;
328             case ANDNOT:
329                 if (result.isEmpty()) // --> no need to execute next filter
330
break;
331                 if ( !filterData.isSiteSearch() ) {
332                     result.andNot(filter.doFilter(filterData.getListId()));
333                 } else {
334                     result.andNot(filter.doFilterBySite(filterData.getSiteId(),
335                             filterData.getContainerDefinitionName(),filterData.getListId()));
336                 }
337                 break;
338             case XOR:
339                 if ( !filterData.isSiteSearch() ) {
340                     result.xor(filter.doFilter(filterData.getListId()));
341                 } else {
342                     result.xor(filter.doFilterBySite(filterData.getSiteId(),
343                             filterData.getContainerDefinitionName(),filterData.getListId()));
344                 }
345                 break;
346             default:
347                 doChain(result, DEFAULT, filter, filterData);
348                 break;
349         }
350     }
351
352     public String JavaDoc toString()
353     {
354         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
355         sb.append("ChainedFilter: [");
356         for (int i = 0; i < chain.length; i++)
357         {
358             if (i>0) {
359                 int logop = (this.logic != -1) ? this.logic : this.logicArray[i-1] ;
360                 switch (logop) {
361                     case OR:
362                         sb.append(" OR ");
363                         break;
364                     case AND:
365                         sb.append(" AND ");
366                         break;
367                     case XOR:
368                         sb.append(" XOR ");
369                         break;
370                     case ANDNOT:
371                         sb.append(" XOR ");
372                         break;
373                     default:
374                         sb.append(" OR ");
375                         break;
376                 }
377             }
378             sb.append(chain[i]);
379             sb.append(' ');
380         }
381         sb.append(']');
382         return sb.toString();
383     }
384
385
386     private class FilterData {
387
388         private int listId;
389         private String JavaDoc containerDefinitionName;
390         private int siteId;
391         private boolean siteSearch = false;
392
393         public FilterData(int listId) {
394             this.listId = listId;
395         }
396
397         public FilterData(int siteId, String JavaDoc containerDefinitionName, int listId) {
398             this.listId = listId;
399             this.containerDefinitionName = containerDefinitionName;
400             this.siteId = siteId;
401             this.siteSearch = true;
402         }
403
404         public int getListId() {
405             return listId;
406         }
407
408         public void setListId(int listId) {
409             this.listId = listId;
410         }
411
412         public String JavaDoc getContainerDefinitionName() {
413             return containerDefinitionName;
414         }
415
416         public void setContainerDefinitionName(String JavaDoc containerDefinitionName) {
417             this.containerDefinitionName = containerDefinitionName;
418         }
419
420         public int getSiteId() {
421             return siteId;
422         }
423
424         public void setSiteId(int siteId) {
425             this.siteId = siteId;
426         }
427
428         public boolean isSiteSearch() {
429             return siteSearch;
430         }
431
432         public void setSiteSearch(boolean siteSearch) {
433             this.siteSearch = siteSearch;
434         }
435     }
436 }
437
Popular Tags