KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jmeter > functions > StringFromFile


1 // $Header: /home/cvs/jakarta-jmeter/src/functions/org/apache/jmeter/functions/StringFromFile.java,v 1.14.2.5 2004/09/21 22:11:12 sebb Exp $
2
/*
3  * Copyright 2003-2004 The Apache Software Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17 */

18
19 package org.apache.jmeter.functions;
20
21 import java.io.BufferedReader JavaDoc;
22 import java.io.FileReader JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.Serializable JavaDoc;
25 import java.text.DecimalFormat JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.LinkedList JavaDoc;
28 import java.util.List JavaDoc;
29
30 import org.apache.jmeter.engine.event.LoopIterationEvent;
31 import org.apache.jmeter.engine.util.CompoundVariable;
32 import org.apache.jmeter.samplers.SampleResult;
33 import org.apache.jmeter.samplers.Sampler;
34 import org.apache.jmeter.testelement.TestListener;
35 import org.apache.jmeter.threads.JMeterVariables;
36 import org.apache.jmeter.util.JMeterUtils;
37 import org.apache.jorphan.logging.LoggingManager;
38 import org.apache.jorphan.util.JMeterStopThreadException;
39 import org.apache.log.Logger;
40
41 /**
42  * StringFromFile Function to read a String from a text file.
43  *
44  * Parameters:
45  * - file name
46  * - variable name (optional - defaults to StringFromFile_)
47  *
48  * Returns:
49  * - the next line from the file - or **ERR** if an error occurs
50  * - value is also saved in the variable for later re-use.
51  *
52  * Ensure that different variable names are used for each call to the function
53  *
54  *
55  * Notes:
56  * - JMeter instantiates a copy of each function for every reference in a
57  * Sampler or elsewhere; each instance will open its own copy of the the file
58  * - the file name is resolved at file (re-)open time
59  * - the output variable name is resolved every time the function is invoked
60  *
61  * @version $Revision: 1.14.2.5 $ Updated on: $Date: 2004/09/21 22:11:12 $
62  */

63 public class StringFromFile
64     extends AbstractFunction
65     implements Serializable JavaDoc, TestListener
66 {
67     private static Logger log = LoggingManager.getLoggerForClass();
68
69     private static final List JavaDoc desc = new LinkedList JavaDoc();
70     private static final String JavaDoc KEY = "_StringFromFile";//$NON-NLS-1$
71
// Function name (only 1 _)
72

73     static final String JavaDoc ERR_IND = "**ERR**";//$NON-NLS-1$
74

75     static {
76         desc.add(JMeterUtils.getResString("string_from_file_file_name"));//$NON-NLS-1$
77
desc.add(JMeterUtils.getResString("function_name_param"));//$NON-NLS-1$
78
desc.add(JMeterUtils.getResString("string_from_file_seq_start"));//$NON-NLS-1$
79
desc.add(JMeterUtils.getResString("string_from_file_seq_final"));//$NON-NLS-1$
80
}
81     private static final int MIN_PARAM_COUNT = 1;
82     private static final int PARAM_NAME = 2;
83     private static final int PARAM_START = 3;
84     private static final int PARAM_END = 4;
85     private static final int MAX_PARAM_COUNT = 4;
86
87     transient private String JavaDoc myValue = ERR_IND;
88     transient private String JavaDoc myName = "StringFromFile_";//$NON-NLS-1$ - Name to store the value in
89
transient private Object JavaDoc[] values;
90     transient private BufferedReader JavaDoc myBread = null; // Buffered reader
91
transient private FileReader JavaDoc fis; // keep this round to close it
92
transient private boolean firstTime = false; // should we try to open the file?
93
transient private String JavaDoc fileName; // needed for error messages
94

95     public StringFromFile()
96     {
97         if (log.isDebugEnabled())
98         {
99             log.debug("++++++++ Construct "+this);
100         }
101     }
102
103     public Object JavaDoc clone()
104     {
105         StringFromFile newReader = new StringFromFile();
106         if (log.isDebugEnabled())
107         { // Skip expensive parameter creation ..
108
log.debug(this +"::StringFromFile.clone()", new Throwable JavaDoc("debug"));//$NON-NLS-1$
109
}
110
111         return newReader;
112     }
113     
114     private void closeFile(){
115         if (myBread == null) return;
116         String JavaDoc tn = Thread.currentThread().getName();
117         log.info(tn + " closing file " + fileName);//$NON-NLS-1$
118
try {
119             myBread.close();
120             fis.close();
121         } catch (IOException JavaDoc e) {
122             log.error("closeFile() error: " + e.toString());//$NON-NLS-1$
123
}
124     }
125
126     private static final int COUNT_UNUSED = -2;
127     private int myStart = COUNT_UNUSED;
128     private int myCurrent = COUNT_UNUSED;
129     private int myEnd = COUNT_UNUSED;
130     
131     private void openFile()
132     {
133         String JavaDoc tn = Thread.currentThread().getName();
134         fileName = ((CompoundVariable) values[0]).execute();
135
136         String JavaDoc start = "";
137         if (values.length >= PARAM_START)
138         {
139             start = ((CompoundVariable) values[PARAM_START-1]).execute();
140             try
141             {
142                 myStart = Integer.valueOf(start).intValue();
143             }
144             catch (NumberFormatException JavaDoc e)
145             {
146                 myStart=COUNT_UNUSED;// Don't process invalid numbers
147
}
148         }
149         // Have we used myCurrent yet?
150
// Set to 1 if start number is missing (to allow for end without start)
151
if (myCurrent == COUNT_UNUSED) myCurrent = myStart == COUNT_UNUSED ? 1 : myStart;
152
153         if (values.length >= PARAM_END)
154         {
155             String JavaDoc tmp = ((CompoundVariable) values[PARAM_END-1]).execute();
156             try
157             {
158                 myEnd = Integer.valueOf(tmp).intValue();
159             }
160             catch (NumberFormatException JavaDoc e)
161             {
162                 myEnd=COUNT_UNUSED;// Don't process invalid numbers (including "")
163
}
164             
165         }
166
167         if (values.length >= PARAM_START)
168         {
169             log.info(tn+" Start = "+myStart+" Current = "+myCurrent+" End = "+myEnd);//$NON-NLS-1$
170
if (myEnd != COUNT_UNUSED){
171                 if (myCurrent > myEnd){
172                     log.info(tn+" No more files to process, "+myCurrent+" > "+myEnd);//$NON-NLS-1$
173
myBread=null;
174                     return;
175                 }
176             }
177             /*
178              * DecimalFormat adds the number to the end of the format if there are
179              * no formatting characters, so we need a way to prevent this from messing
180              * up the file name.
181              *
182              */

183             if (myStart != COUNT_UNUSED) // Only try to format if there is a number
184
{
185                 log.info(tn + " using format "+fileName);
186                 try {
187                     DecimalFormat JavaDoc myFormatter = new DecimalFormat JavaDoc(fileName);
188                     fileName = myFormatter.format(myCurrent);
189                 }
190                 catch (NumberFormatException JavaDoc e)
191                 {
192                     log.warn("Bad file name format ",e);
193                 }
194             }
195             myCurrent++;// for next time
196
}
197
198         log.info(tn + " opening file " + fileName);//$NON-NLS-1$
199
try
200         {
201             fis = new FileReader JavaDoc(fileName);
202             myBread = new BufferedReader JavaDoc(fis);
203         }
204         catch (Exception JavaDoc e)
205         {
206             log.error("openFile() error: " + e.toString());//$NON-NLS-1$
207
myBread=null;
208         }
209     }
210
211     /* (non-Javadoc)
212      * @see org.apache.jmeter.functions.Function#execute(SampleResult, Sampler)
213      */

214     public synchronized String JavaDoc execute(
215         SampleResult previousResult,
216         Sampler currentSampler)
217         throws InvalidVariableException
218     {
219
220         JMeterVariables vars = getVariables();
221
222         if (values.length >= PARAM_NAME)
223         {
224             myName = ((CompoundVariable) values[PARAM_NAME-1]).execute();
225         }
226
227         myValue = ERR_IND;
228         
229         /*
230          * To avoid re-opening the file repeatedly after an error,
231          * only try to open it in the first execute() call
232          * (It may be re=opened at EOF, but that will cause at most
233          * one failure.)
234          */

235         if (firstTime) {
236             openFile();
237             firstTime=false;
238         }
239         
240         if (null != myBread)
241         { // Did we open the file?
242
try
243             {
244                 String JavaDoc line = myBread.readLine();
245                 if (line == null)
246                 { // EOF, re-open file
247
String JavaDoc tn = Thread.currentThread().getName();
248                     log.info(tn+" EOF on file " + fileName);//$NON-NLS-1$
249
closeFile();
250                     openFile();
251                     if (myBread != null) {
252                         line = myBread.readLine();
253                     } else {
254                         line = ERR_IND;
255                         if (myEnd != COUNT_UNUSED){// Are we processing a file sequence?
256
log.info(tn + " Detected end of sequence.");
257                             throw new JMeterStopThreadException("End of sequence");
258                         }
259                     }
260                 }
261                 myValue = line;
262             }
263             catch (IOException JavaDoc e)
264             {
265                 String JavaDoc tn = Thread.currentThread().getName();
266                 log.error(tn + " error reading file " + e.toString());//$NON-NLS-1$
267
}
268         } else { // File was not opened successfully
269
if (myEnd != COUNT_UNUSED){// Are we processing a file sequence?
270
String JavaDoc tn = Thread.currentThread().getName();
271                 log.info(tn + " Detected end of sequence.");
272                 throw new JMeterStopThreadException("End of sequence");
273             }
274         }
275
276         if (myName.length() > 0){
277             vars.put(myName, myValue);
278         }
279         
280         if (log.isDebugEnabled()){
281             String JavaDoc tn = Thread.currentThread().getName();
282             log.debug(tn + " name:" //$NON-NLS-1$
283
+ myName + " value:" + myValue);//$NON-NLS-1$
284
}
285         
286         return myValue;
287
288     }
289
290     /* (non-Javadoc)
291      * Parameters:
292      * - file name
293      * - variable name (optional)
294      * - start index (optional)
295      * - end index or count (optional)
296      *
297      * @see org.apache.jmeter.functions.Function#setParameters(Collection)
298      */

299     public synchronized void setParameters(Collection JavaDoc parameters)
300         throws InvalidVariableException
301     {
302
303         log.debug(this +"::StringFromFile.setParameters()");//$NON-NLS-1$
304

305         values = parameters.toArray();
306
307         if ((values.length > MAX_PARAM_COUNT) || (values.length < MIN_PARAM_COUNT))
308         {
309             throw new InvalidVariableException("Wrong number of parameters");//$NON-NLS-1$
310
}
311
312         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(40);
313         sb.append("setParameters(");//$NON-NLS-1$
314
for (int i = 0; i< values.length;i++){
315             if (i > 0) sb.append(",");
316             sb.append(((CompoundVariable) values[i]).getRawParameters());
317         }
318         sb.append(")");//$NON-NLS-1$
319
log.info(sb.toString());
320         
321         
322         //N.B. setParameters is called before the test proper is started,
323
// and thus variables are not interpreted at this point
324
// So defer the file open until later to allow variable file names to be used.
325
firstTime = true;
326     }
327
328     /* (non-Javadoc)
329      * @see org.apache.jmeter.functions.Function#getReferenceKey()
330      */

331     public String JavaDoc getReferenceKey()
332     {
333         return KEY;
334     }
335
336     /* (non-Javadoc)
337      * @see org.apache.jmeter.functions.Function#getArgumentDesc()
338      */

339     public List JavaDoc getArgumentDesc()
340     {
341         return desc;
342     }
343
344     public void testStarted()
345     {
346         //
347
}
348
349     public void testStarted(String JavaDoc host)
350     {
351         //
352
}
353
354     public void testEnded()
355     {
356         this.testEnded("");
357     }
358
359     public void testEnded(String JavaDoc host)
360     {
361         closeFile();
362     }
363
364     public void testIterationStart(LoopIterationEvent event)
365     {
366         //
367
}
368 }
Popular Tags