Coverage report

| %line | %branch
--- | --- | ---

org.apache.commons.jelly.tags.core.ForEachTag

89%

100%

1

     /*

2

      * Copyright 2002,2004 The Apache Software Foundation.

3

      *

4

      * Licensed under the Apache License, Version 2.0 (the "License");

5

      * you may not use this file except in compliance with the License.

6

      * You may obtain a copy of the License at

7

      *

8

      *      http://www.apache.org/licenses/LICENSE-2.0

9

      *

10

      * Unless required by applicable law or agreed to in writing, software

11

      * distributed under the License is distributed on an "AS IS" BASIS,

12

      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

13

      * See the License for the specific language governing permissions and

14

      * limitations under the License.

15

      */

16

17

     package org.apache.commons.jelly.tags.core;

18

19

     import java.util.Iterator;

20

21

     import javax.servlet.jsp.jstl.core.LoopTagStatus;

22

23

     import org.apache.commons.jelly.JellyTagException;

24

     import org.apache.commons.jelly.MissingAttributeException;

25

     import org.apache.commons.jelly.TagSupport;

26

     import org.apache.commons.jelly.XMLOutput;

27

     import org.apache.commons.jelly.expression.Expression;

28

     import org.apache.commons.jelly.impl.BreakException;

29

     import org.apache.commons.logging.Log;

30

     import org.apache.commons.logging.LogFactory;

31

32

     /**

33

       * Iterates over a collection, iterator or an array of objects.

34

       * Uses the same syntax as the <a href="http://java.sun.com/products/jsp/jstl/">JSTL</a>

35

       * <code>forEach</code> tag does.

36

       *

37

       * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>

38

       * @version $Revision: 155420 $

39

       */

40

     public class ForEachTag extends TagSupport {

41

42

         /** The Log to which logging calls will be made. */

43

546

         private static final Log log = LogFactory.getLog(ForEachTag.class);

44

45

         /** Holds the variable name to export for the item being iterated over. */

46

         private Expression items;

47

48

         /**

49

          * If specified then the current item iterated through will be defined

50

          * as the given variable name.

51

          */

52

         private String var;

53

54

         /**

55

          * If specified then the current index counter will be defined

56

          * as the given variable name.

57

          */

58

         private String indexVar;

59

60

         /** variable to hold loop status */

61

         private String statusVar;

62

63

         /** The starting index value */

64

         private int begin;

65

66

         /** The ending index value */

67

351

         private int end = Integer.MAX_VALUE;

68

69

         /** The index increment step */

70

351

         private int step = 1;

71

72

         /** The iteration index */

73

         private int index;

74

75

351

         public ForEachTag() {

76

351

         }

77

78

         // Tag interface

79

80

         //-------------------------------------------------------------------------

81

         public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException {

82

83

351

             if (log.isDebugEnabled()) {

84

0

                 log.debug("running with items: " + items);

85

             }

86

87

             try {

88

351

                 if (items != null) {

89

52

                     Iterator iter = items.evaluateAsIterator(context);

90

91

52

                     if (log.isDebugEnabled()) {

92

0

                         log.debug("Iterating through: " + iter);

93

                     }

94

95

                     // ignore the first items of the iterator

96

78

                     for (index = 0; index < begin && iter.hasNext(); index++ ) {

97

26

                         iter.next();

98

                     }

99

100

                     // set up the status

101

52

                     LoopStatus status = null;

102

52

                     if (statusVar != null)

103

                     {

104

                         // set up statii as required by JSTL

105

13

                         Integer statusBegin = (begin == 0) ? null : new Integer(begin);

106

13

                         Integer statusEnd = (end == Integer.MAX_VALUE) ? null : new Integer(end);

107

13

                         Integer statusStep = (step == 1) ? null : new Integer(step);

108

13

                         status = new LoopStatus(statusBegin, statusEnd, statusStep);

109

13

                         context.setVariable(statusVar, status);

110

                     }

111

112

52

                     boolean firstTime = true;

113

52

                     int count = 0;

114

195

                     while (iter.hasNext() && index <= end) {

115

143

                         Object value = iter.next();

116

143

                         if (var != null) {

117

143

                             context.setVariable(var, value);

118

                         }

119

143

                         if (indexVar != null) {

120

0

                             context.setVariable(indexVar, new Integer(index));

121

                         }

122

                         // set the status var up

123

143

                         if (statusVar != null) {

124

39

                             count++;

125

39

                             status.setCount(count);

126

39

                             status.setCurrent(value);

127

39

                             status.setFirst(firstTime);

128

39

                             status.setIndex(index);

129

                             // set first time up for the next iteration.

130

39

                             if (firstTime) {

131

13

                                 firstTime = !firstTime;

132

                             }

133

                         }

134

                         // now we need to work out the next index for status isLast

135

                         // and also advance the iterator and index for the loop.

136

143

                         boolean finished = false;

137

143

                         index++;

138

182

                         for ( int i = 1; i < step && !finished; i++, index++ ) {

139

39

                             if ( ! iter.hasNext() ) {

140

0

                                finished = true;

141

0

                             }

142

                             else {

143

39

                                 iter.next();

144

                             }

145

                         }

146

147

143

                         if (statusVar != null) {

148

39

                             status.setLast(finished || !iter.hasNext() || index > end);

149

                         }

150

143

                         invokeBody(output);

151

152

143

                     }

153

52

                 }

154

                 else {

155

299

                     if ( end == Integer.MAX_VALUE && begin == 0 ) {

156

0

                         throw new MissingAttributeException( "items" );

157

                     }

158

                     else {

159

299

                         String varName = var;

160

299

                         if ( varName == null ) {

161

0

                             varName = indexVar;

162

                         }

163

                         // set up the status

164

299

                         LoopStatus status = null;

165

299

                         if (statusVar != null)

166

                         {

167

                             // set up statii as required by JSTL

168

13

                             Integer statusBegin = new Integer(begin);

169

13

                             Integer statusEnd = new Integer(end);

170

13

                             Integer statusStep = new Integer(step);

171

13

                             status = new LoopStatus(statusBegin, statusEnd, statusStep);

172

13

                             context.setVariable(statusVar, status);

173

                         }

174

175

299

                         int count = 0;

176

1716

                         for (index = begin; index <= end; index += step ) {

177

178

1599

                             Object value = new Integer(index);

179

1599

                             if (varName != null) {

180

1599

                                 context.setVariable(varName, value);

181

                             }

182

                             // set the status var up

183

1599

                             if (status != null) {

184

39

                                 count++;

185

39

                                 status.setIndex(index);

186

39

                                 status.setCount(count);

187

39

                                 status.setCurrent(value);

188

39

                                 status.setFirst(index == begin);

189

39

                                 status.setLast(index > end - step);

190

                             }

191

1599

                             invokeBody(output);

192

                         }

193

                     }

194

                 }

195

             }

196

182

             catch (BreakException e) {

197

182

                 if (log.isDebugEnabled()) {

198

0

                     log.debug("loop terminated by break: " + e, e);

199

                 }

200

169

             }

201

351

         }

202

203

         // Properties

204

         //-------------------------------------------------------------------------

205

206

         /**

207

          * Sets the expression used to iterate over.

208

          * This expression could resolve to an Iterator, Collection, Map, Array,

209

          * Enumeration or comma separated String.

210

          */

211

         public void setItems(Expression items) {

212

52

             this.items = items;

213

52

         }

214

215

         /** Sets the variable name to export for the item being iterated over

216

          */

217

         public void setVar(String var) {

218

351

             this.var = <span class="keyword">var;

219

351

         }

220

221

         /** Sets the variable name to export the current index counter to

222

          */

223

         public void setIndexVar(String indexVar) {

224

0

             this.indexVar = indexVar;

225

0

         }

226

227

         /** Sets the starting index value

228

          */

229

         public void setBegin(int begin) {

230

312

             this.begin = begin;

231

312

         }

232

233

         /** Sets the ending index value

234

          */

235

         public void setEnd(int end) {

236

312

             this.end = end;

237

312

         }

238

239

         /** Sets the index increment step

240

          */

241

         public void setStep(int step) {

242

26

             this.step = step;

243

26

         }

244

245

         /**

246

          * Sets the variable name to export the current status to.

247

          * The status is an implementation of the JSTL LoopTagStatus interface that provides

248

          * the following bean properties:

249

          * <ul>

250

          *   <li>current - the current value of the loop items being iterated</li>

251

          *   <li>index   - the current index of the items being iterated</li>

252

          *   <li>first   - true if this is the first iteration, false otherwise</li>

253

          *   <li>last    - true if this is the last iteration, false otherwise</li>

254

          *   <li>begin   - the starting index of the loop</li>

255

          *   <li>step    - the stepping value of the loop</li>

256

          *   <li>end     - the end index of the loop</li>

257

          * </ul>

258

          */

259

         public void setVarStatus(String var) {

260

26

             this.statusVar = var;

261

26

         }

262

263

         /**

264

          * Holds the status of the loop.

265

          */

266

         public static final class LoopStatus implements LoopTagStatus

267

         {

268

             private Integer begin;

269

             private int count;

270

             private Object current;

271

             private Integer end;

272

             private int index;

273

             private Integer step;

274

             private boolean first;

275

             private boolean last;

276

277

             public LoopStatus(Integer begin, Integer end, Integer step) {

278

                 this.begin = begin;

279

                 this.end = end;

280

                 this.step = step;

281

             }

282

             /**

283

              * @return Returns the begin.

284

              */

285

             public Integer getBegin() {

286

                 return begin;

287

             }

288

             /**

289

              * @return Returns the count.

290

              */

291

             public int getCount() {

292

                 return count;

293

             }

294

             /**

295

              * @return Returns the current.

296

              */

297

             public Object getCurrent() {

298

                 return current;

299

             }

300

             /**

301

              * @return Returns the end.

302

              */

303

             public Integer getEnd() {

304

                 return end;

305

             }

306

             /**

307

              * @return Returns the first.

308

              */

309

             public boolean isFirst() {

310

                 return first;

311

             }

312

             /**

313

              * @return Returns the index.

314

              */

315

             public int getIndex() {

316

                 return index;

317

             }

318

             /**

319

              * @return Returns the last.

320

              */

321

             public boolean isLast() {

322

                 return last;

323

             }

324

             /**

325

              * @return Returns the step.

326

              */

327

             public Integer getStep() {

328

                 return step;

329

             }

330

             /**

331

              * @param count The count to set.

332

              */

333

             public void setCount(int count) {

334

                 this.count = count;

335

             }

336

             /**

337

              * @param current The current to set.

338

              */

339

             public void setCurrent(Object current) {

340

                 this.current = current;

341

             }

342

             /**

343

              * @param first The first to set.

344

              */

345

             public void setFirst(boolean first) {

346

                 this.first = first;

347

             }

348

             /**

349

              * @param last The last to set.

350

              */

351

             public void setLast(boolean last) {

352

                 this.last = last;

353

             }

354

             /**

355

              * @param index The index to set.

356

              */

357

             public void setIndex(int index) {

358

                 this.index = index;

359

             }

360

         }

361

     }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.