1/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2 *
3 * This program and the accompanying materials are made available under
4 * the terms of the Common Public License v1.0 which accompanies this distribution,
5 * and is available at http://www.eclipse.org/legal/cpl-v10.html
6 *
7 * $Id: IInclExclFilter.java,v 1.1.1.1 2004/05/09 16:57:33 vlad_r Exp $
8 */
9package com.vladium.emma.filter;
10
11import java.util.ArrayList;
12import java.util.Iterator;
13import java.util.List;
14import java.util.StringTokenizer;
15
16import com.vladium.util.WCMatcher;
17
18// ----------------------------------------------------------------------------
19/**
20 * @author Vlad Roubtsov, 2003
21 */
22public
23interface IInclExclFilter
24{
25    // public: ................................................................
26
27    // TODO: move this into util pkg
28
29    char INCLUSION_PREFIX = '+';
30    String INCLUSION_PREFIX_STRING = "+";
31    char EXCLUSION_PREFIX = '-';
32    String EXCLUSION_PREFIX_STRING = "-";
33
34    boolean included (final String s);
35
36    abstract class Factory
37    {
38        public static IInclExclFilter create (final String specs1, final String separators, final String [] specs2)
39        {
40            if ((specs1 == null) || (specs1.trim ().length () == 0))
41                return create (specs2);
42            else
43            {
44                final List /* String */ _specs = new ArrayList ();
45
46                if (specs2 != null)
47                {
48                    for (int s = 0; s < specs2.length; ++ s)
49                    {
50                        _specs.add (specs2 [s]);
51                    }
52                }
53
54                for (StringTokenizer tokenizer = new StringTokenizer (specs1, separators);
55                     tokenizer.hasMoreTokens (); )
56                {
57                    _specs.add (tokenizer.nextToken ());
58                }
59
60                final String [] specs = new String [_specs.size ()];
61                _specs.toArray (specs);
62
63                return create (specs);
64            }
65        }
66
67        public static IInclExclFilter create (final String [] specs)
68        {
69            if ((specs == null) || (specs.length == 0))
70                return new WCInclExclFilter ((String []) null, (String []) null);
71
72            final List inclusions = new ArrayList ();
73            final List exclusions = new ArrayList ();
74
75            for (int i = 0, iLimit = specs.length; i < iLimit; ++ i)
76            {
77                final String spec = specs [i];
78
79                if (spec.length () > 0)
80                {
81                    if (spec.charAt (0) == EXCLUSION_PREFIX)
82                        exclusions.add (spec.substring (1));
83                    else
84                    {
85                        // [inclusion prefix is optional]
86
87                        if (spec.charAt (0) == INCLUSION_PREFIX)
88                            inclusions.add (spec.substring (1));
89                        else
90                            inclusions.add (spec);
91                    }
92                }
93            }
94
95            return new WCInclExclFilter (inclusions, exclusions);
96        }
97
98        public static IInclExclFilter create (final String [] inclusions,
99                                              final String [] exclusions)
100        {
101            return new WCInclExclFilter (inclusions, exclusions);
102        }
103
104        public static IInclExclFilter create (final List /* String */ inclusions,
105                                              final List /* String */ exclusions)
106        {
107            return new WCInclExclFilter (inclusions, exclusions);
108        }
109
110        private static final class WCInclExclFilter implements IInclExclFilter
111        {
112            public boolean included (final String s)
113            {
114                if (s == null) return false;
115
116                final char [] chars = s.toCharArray ();
117
118                // included set is (inclusions - exclusions), where null inclusions
119                // mean 'everything' and null exclusions mean 'nothing':
120
121                final WCMatcher [] inclusions = m_inclusions;
122                final WCMatcher [] exclusions = m_exclusions;
123
124                if (inclusions != null)
125                {
126                    boolean included = false;
127
128                    for (int i = 0, iLimit = inclusions.length; i < iLimit; ++ i)
129                    {
130                        if (inclusions [i].matches (chars))
131                        {
132                            included = true;
133                            break;
134                        }
135                    }
136
137                    if (! included) return false;
138                }
139
140                if (exclusions != null)
141                {
142                    for (int x = 0, xLimit = exclusions.length; x < xLimit; ++ x)
143                    {
144                        if (exclusions [x].matches (chars)) return false;
145                    }
146                }
147
148                return true;
149            }
150
151
152            WCInclExclFilter (final String [] inclusions,
153                              final String [] exclusions)
154            {
155                if ((inclusions == null) || (inclusions.length == 0))
156                    m_inclusions = null;
157                else
158                {
159                    m_inclusions = new WCMatcher [inclusions.length];
160
161                    for (int i = 0; i < inclusions.length; ++ i)
162                    {
163                        m_inclusions [i] = WCMatcher.compile (inclusions [i]);
164                    }
165                }
166
167                if ((exclusions == null) || (exclusions.length == 0))
168                    m_exclusions = null;
169                else
170                {
171                    m_exclusions = new WCMatcher [exclusions.length];
172
173                    for (int i = 0; i < exclusions.length; ++ i)
174                    {
175                        m_exclusions [i] = WCMatcher.compile (exclusions [i]);
176                    }
177                }
178            }
179
180            WCInclExclFilter (final List /* String */ inclusions,
181                              final List /* String */ exclusions)
182            {
183                if ((inclusions == null) || inclusions.isEmpty ())
184                    m_inclusions = null;
185                else
186                {
187                    m_inclusions = new WCMatcher [inclusions.size ()];
188
189                    int ii = 0;
190                    for (Iterator i = inclusions.iterator (); i.hasNext (); ++ ii)
191                    {
192                        final String pattern = (String) i.next ();
193
194                        m_inclusions [ii] = WCMatcher.compile (pattern);
195                    }
196                }
197
198                if ((exclusions == null) || exclusions.isEmpty ())
199                    m_exclusions = null;
200                else
201                {
202                    m_exclusions = new WCMatcher [exclusions.size ()];
203
204                    int ii = 0;
205                    for (Iterator i = exclusions.iterator (); i.hasNext (); ++ ii)
206                    {
207                        final String pattern = (String) i.next ();
208
209                        m_exclusions [ii] = WCMatcher.compile (pattern);
210                    }
211                }
212            }
213
214
215            private final WCMatcher [] m_inclusions, m_exclusions;
216
217        } // end of nested class
218
219    } // end of nested class
220
221} // end of interface
222// ----------------------------------------------------------------------------