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.generation;
33  
34  //==============================================================================
35  
36  import java.util.HashMap;
37  import java.util.Map;
38  
39  import com.unitesk.atp.dynattrs.Accessor;
40  import com.unitesk.atp.dynattrs.Attributed;
41  import com.unitesk.atp.dynattrs.MapAttributed;
42  import com.unitesk.atp.text.filters.PatternFilter;
43  import com.unitesk.atp.text.filters.TextReceiver;
44  
45  //==============================================================================
46  
47  /***
48   * The basic implementation of {@link Generator} interface.
49   * Processed text is passed to client {@link TextReceiver text receiver}.
50   *
51   * @author <A href="mailto:demakov@ispras.ru">Alexey Demakov</A>
52   * @version $Id: BasicGenerator.java,v 1.2 2004/10/11 15:51:32 all-x Exp $
53   */
54  public class BasicGenerator
55      implements Generator, PatternFilter.ParameterProcessor
56  {
57      //--------------------------------------------------------------------------
58      // constructors
59  
60      /***
61       * Constructs generator with the specified client.
62       *
63       * @param  client  The client text receiver.
64       */
65      public BasicGenerator( TextReceiver client )
66      {
67          this( client, new DefaultFunction(), "${", "}" );
68      }
69  
70      /***
71       * Constructs generator with the specified parameters.
72       *
73       * @param  client  The client text receiver.
74       * @param  default_func
75       *                 The default function
76       * @param  par_start
77       *                 The parameter start delimemter
78       * @throws  NullPointerException     If client == null
79       */
80      public BasicGenerator( TextReceiver client
81                           , Function default_func
82                           , String par_start
83                           , String par_end
84                           )
85      {
86          if( client == null )
87          {
88              throw new NullPointerException();
89          }
90  
91          this.client = client;
92  
93          pattern_filter = new PatternFilter( client, this, par_start, par_end );
94  
95          setFunction( DEFAULT_NAME, default_func );
96      }
97  
98      //--------------------------------------------------------------------------
99      // interface Generator
100 
101     /***
102      * {@inheritDoc}
103      */
104     public Function setFunction( String name, Function func )
105     {
106         mustBeID( name );
107 
108         Function res;
109 
110         if( func != null )
111         {
112             func.setGenerator( this );
113             res = (Function)name_to_func.put( name, func );
114         } else {
115             res = (Function)name_to_func.remove( name );
116         }
117         if( res != null && res != func )
118         {
119             /*
120              * free function
121              */
122             res.setGenerator( null );
123         }
124         return res;
125     }
126 
127     /***
128      * {@inheritDoc}
129      */
130     public Function getFunction( String name )
131     {
132         mustBeID( name );
133 
134         return (Function)name_to_func.get( name );
135     }
136 
137     /***
138      * {@inheritDoc}
139      */
140     public Object setVariable( String name, Object var )
141     {
142         mustBeID( name );
143 
144         if( var != null )
145         {
146             return name_to_var.put( name, var );
147         } else {
148             return name_to_var.remove( name );
149         }
150     }
151 
152     /***
153      * {@inheritDoc}
154      */
155     public Object getVariable( String name )
156     {
157         mustBeID( name );
158 
159         return name_to_var.get( name );
160     }
161 
162     /***
163      * {@inheritDoc}
164      */
165     public void txt( String str )
166     {
167         pattern_filter.txt( str );
168     }
169 
170     /***
171      * {@inheritDoc}
172      */
173     public void txtAsIs( String str )
174     {
175         client.txt( str );
176     }
177 
178     //--------------------------------------------------------------------------
179     // interface PatternFilter.ParameterProcessor
180 
181     /***
182      * {@inheritDoc}
183      */
184     public void param( String param )
185     {
186         int colon = param.indexOf( ':' );
187 
188         String func;
189         int arg_pos;
190 
191         if( colon == -1 )
192         {
193             func = DEFAULT_NAME;
194             arg_pos = 0;
195         } else {
196             func = param.substring( 0, colon );
197             arg_pos = colon + 1;
198         }
199 
200         Function f;
201         try
202         {
203             f = getFunction( func );
204         }
205         catch( IllegalArgumentException e )
206         {
207             f = null;
208         }
209 
210         if( f == null )
211         {
212             throw new UndefinedFunctionException( param, func );
213         }
214 
215         Object var_obj;
216 
217         int param_len = param.length();
218         if( arg_pos < param_len && param.charAt( arg_pos ) == '.' )
219         {
220             /*
221              * 'absolute' path starts from variable name.
222              * get it from variable map
223              */
224             var_obj = variable_map;
225             arg_pos++;
226         } else {
227             // use default variable
228             var_obj = getVariable( DEFAULT_NAME );
229         }
230 
231         Object arg_obj;
232 
233         if( arg_pos == param_len )
234         {
235             arg_obj = var_obj;
236         } else {
237             int question = param.indexOf( "?", arg_pos );
238             String arg;
239 
240             if( question != -1 )
241             {
242                 arg = param.substring( arg_pos, question );
243             } else {
244                 arg = param.substring( arg_pos );
245             }
246 
247             arg_obj = Accessor.getAttribute( var_obj
248                                            , arg
249                                            , variable_map
250                                            );
251 
252             if( arg_obj == null && question != -1 )
253             {
254                 arg_obj = param.substring( question + 1 );
255             }
256         }
257 
258         f.process( arg_obj );
259     }
260 
261     //--------------------------------------------------------------------------
262     // implementation
263 
264     protected void mustBeID( String id )
265     {
266         if( id.length() > 0 && !Accessor.isID( id ) )
267         {
268            throw new IllegalArgumentException( id );
269         }
270     }
271 
272     protected Map/*String,Function*/ name_to_func
273         = new HashMap/*String,Function*/();
274 
275     protected Map/*String,Object*/ name_to_var
276         = new HashMap/*String,Object*/();
277 
278     protected Attributed variable_map = new MapAttributed( name_to_var );
279 
280     protected PatternFilter pattern_filter;
281 
282     protected TextReceiver client;
283 }