View Javadoc

1   /*
2    * Copyright (c) 2001-2004,
3    * RedVerst Group, ISP RAS http://www.ispras.ru
4    * All rights reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions are met:
8    *
9    * 1. Redistributions of source code must retain the above copyright notice, this
10   *    list of conditions and the following disclaimer.
11   *
12   * 2. Redistributions in binary form must reproduce the above copyright notice,
13   *    this list of conditions and the following disclaimer in the documentation
14   *    and/or other materials provided with the distribution.
15   *
16   * 3. The names "ATP", "TreeDL", "RedVerst", "ISP RAS"
17   *    may not be used to endorse or promote products derived from this software
18   *    without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  
32  package com.unitesk.atp.text.filters;
33  
34  /***
35   * This filter interprets strings as patterns.
36   * A pattern can have parameters limited
37   * by <I>&lt;parameter_start&gt;</I> and <I>&lt;parameter_end&gt;</I>
38   * (<B>${</B> and <B>}</B> by default).
39   * Parameters are passed to {@link ParameterProcessor parameter processor}
40   * and the rest of line - to the client of filter.
41   * The special case - empty parameter always stands as escaping of
42   * <I>&lt;parameter_start&gt;</I> and don't passed to parameter processor.
43   * <I>&lt;parameter_start&gt;</I> is passed to the client instead.
44   * Parameters can't be nested.
45   * The way of parameters processing depends on processor. For example
46   * it can treat them as alias names, replace by values and pass
47   * to the same client.
48   *
49   * @author <A href="mailto:demakov@ispras.ru">Alexey Demakov</A>
50   * @version $Id: PatternFilter.java,v 1.1 2004/10/09 06:36:40 all-x Exp $
51   */
52  public class PatternFilter extends Filter
53  {
54      /***
55       * Processor of pattern parameters.
56       */
57      public interface ParameterProcessor
58      {
59          /***
60           * Receives pattern parameter (without delimeters)
61           *
62           * @param s   the pattern parameters.
63           */
64          void param( String s );
65      }
66  
67      /***
68       * Constructs pattern filter with default parameter delimeters
69       * <B>$(</B> and <B>)</B>.
70       *
71       * @param  client  The client of filter.
72       * @param  parameter_processor
73       *                 The processor of pattern parameters.
74       * @throws NullPointerException
75       *                 If any of the parameters is <code>null</code>
76       */
77      public PatternFilter( TextReceiver client
78                          , ParameterProcessor parameter_processor
79                          )
80      {
81          super( client );
82  
83          if( parameter_processor == null )
84          {
85              throw new NullPointerException();
86          }
87  
88          this.parameter_processor = parameter_processor;
89      }
90  
91      /***
92       * Constructs pattern filter with the specified parameter delimeters.
93       *
94       * @param  client  The client of filter.
95       * @param  parameter_processor
96       *                 The processor of pattern parameters.
97       * @param  parameter_start
98       *                 The parameter start delimeter.
99       * @param  parameter_end
100      *                 The parameter end delimeter.
101      * @throws NullPointerException
102      *                 If any of the parameters is <code>null</code>
103      *                 or any of the delimeters is an empty string.
104      */
105     public PatternFilter( TextReceiver client
106                         , ParameterProcessor parameter_processor
107                         , String parameter_start
108                         , String parameter_end
109                         )
110     {
111         this( client, parameter_processor );
112 
113         if(    parameter_start == null
114             || parameter_end == null
115             || parameter_start.length() == 0
116             || parameter_end.length() == 0
117           )
118         {
119             throw new NullPointerException();
120         }
121 
122         this.parameter_start = parameter_start;
123         this.parameter_end   = parameter_end;
124     }
125 
126     //--------------------------------------------------------------------------
127     // interface TextReceiver
128 
129     /***
130      * Receives the string and interprets it as pattern.
131      * A pattern can have parameters limited
132      * by <I>&lt;parameter_start&gt;</I> and <I>&lt;parameter_end&gt;</I>
133      * (<B>$(</B> and <B>)</B> by default).
134      * Parameters are passed to {@link ParameterProcessor parameter processor}
135      * and the rest of line - to the filter client.
136      * The special case - empty parameter always stands as escaping of
137      * <I>&lt;parameter_start&gt;</I> and don't passed to parameter processor.
138      * <I>&lt;parameter_start&gt;</I> is passed to the client instead.
139      * Parameters can't be nested.
140      *
141      * @param s   the pattern
142      * @throws FilterException
143      *         inheritors can use it for their own purposes
144      */
145     public void txt( String s )
146     {
147         int len = s.length();
148 
149         for( int i = 0; i < len; )
150         {
151             // skip all before parameter_start
152             int j = s.indexOf( parameter_start, i );
153             if( j < 0 ) j = len;
154             if( i < j )
155             {
156                 client.txt( s.substring( i, j ) );
157                 i = j;
158             }
159             if( i == len ) continue;
160             // skip parameter_start
161             i += parameter_start.length();
162             // find parameter
163             j = s.indexOf( parameter_end, i );
164             if( j < 0 )
165             {
166                 throw new IllegalArgumentException( i + ":" + s );
167             }
168             if( i == j )
169             {
170                 // special case
171                 client.txt( parameter_start );
172             } else {
173                 parameter_processor.param( s.substring( i, j ) );
174             }
175             i = j + parameter_end.length();
176         }
177     }
178 
179     //--------------------------------------------------------------------------
180     // implementation
181 
182     private ParameterProcessor parameter_processor;
183     private String parameter_start = "${";
184     private String parameter_end   = "}";
185 }