Coverage Report - org.apache.myfaces.view.facelets.impl.SectionUniqueIdCounter
 
Classes in this File Line Coverage Branch Coverage Complexity
SectionUniqueIdCounter
0%
0/121
0%
0/46
2.632
SectionUniqueIdCounter$Section
0%
0/30
0%
0/8
2.632
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.myfaces.view.facelets.impl;
 20  
 
 21  
 import java.util.ArrayList;
 22  
 import java.util.List;
 23  
 
 24  
 /**
 25  
  * Hierarchical counter to generate unique ids.
 26  
  * 
 27  
  * @author Leonardo Uribe
 28  
  *
 29  
  */
 30  0
 public class SectionUniqueIdCounter
 31  
 {
 32  
     private List<Section> _counterStack;
 33  
     
 34  
     private int _activeSection;
 35  
     
 36  
     private final String _prefix;
 37  
     
 38  
     private final StringBuilder _builder;
 39  
     
 40  
     private char[] _bufferConversion;
 41  
     
 42  
     private final int _radix;
 43  
     
 44  
     private final String[] _uniqueIdsCache;
 45  
     
 46  
     public SectionUniqueIdCounter()
 47  0
     {
 48  0
         _activeSection = 0;
 49  0
         _radix = Character.MAX_RADIX;
 50  0
         _counterStack = new ArrayList<Section>();
 51  0
         _counterStack.add(new Section(null,1,_radix));
 52  0
         _prefix = null;
 53  0
         _builder = new StringBuilder(30);
 54  0
         _bufferConversion = new char[15];
 55  0
         _uniqueIdsCache = null;
 56  0
     }
 57  
     
 58  
     public SectionUniqueIdCounter(String prefix)
 59  0
     {
 60  0
         _activeSection = 0;
 61  0
         _radix = Character.MAX_RADIX;
 62  0
         _counterStack = new ArrayList<Section>();
 63  0
         _counterStack.add(new Section(null,1,_radix));
 64  0
         _prefix = prefix;
 65  0
         _builder = new StringBuilder(30);
 66  0
         _bufferConversion = new char[15];
 67  0
         _uniqueIdsCache = null;
 68  0
     }
 69  
     
 70  
     public SectionUniqueIdCounter(String prefix, String[] cache)
 71  0
     {
 72  0
         _activeSection = 0;
 73  0
         _radix = Character.MAX_RADIX;
 74  0
         _counterStack = new ArrayList<Section>();
 75  0
         _counterStack.add(new Section(null,1,_radix));
 76  0
         _prefix = prefix;
 77  0
         _builder = new StringBuilder(30);
 78  0
         _bufferConversion = new char[15];
 79  0
         _uniqueIdsCache = cache;
 80  0
     }
 81  
     
 82  
     public SectionUniqueIdCounter(String prefix, int radix)
 83  0
     {
 84  0
         _activeSection = 0;
 85  0
         _radix = radix;
 86  0
         _counterStack = new ArrayList<Section>();
 87  0
         _counterStack.add(new Section(null,1,_radix));
 88  0
         _prefix = prefix;
 89  0
         _builder = new StringBuilder(30);
 90  0
         _bufferConversion = new char[15];
 91  0
         _uniqueIdsCache = null;
 92  0
     }
 93  
 
 94  
     /**
 95  
      * Creates an array of the generated unique ids for an specified prefix,
 96  
      * than can be used later to prevent calculate the same String over and over.
 97  
      * 
 98  
      * @param prefix
 99  
      * @param count
 100  
      * @return 
 101  
      */
 102  
     public static String[] generateUniqueIdCache(String prefix, int count)
 103  
     {
 104  0
         String[] cache = new String[count];
 105  0
         SectionUniqueIdCounter counter = new SectionUniqueIdCounter(prefix);
 106  0
         for (int i = 0; i < count ; i++)
 107  
         {
 108  0
             cache[i] = counter.generateUniqueId();
 109  
         }
 110  0
         return cache;
 111  
     }
 112  
 
 113  
     public String startUniqueIdSection()
 114  
     {
 115  
         //1. Calculate prefix
 116  0
         _builder.delete(0, _builder.length());
 117  
         
 118  0
         if (!_counterStack.isEmpty())
 119  
         {
 120  0
             String lastPrefix = _counterStack.get(_counterStack.size()-1).getPrefix();
 121  0
             if (lastPrefix != null)
 122  
             {
 123  0
                 _builder.append(lastPrefix);
 124  0
                 _builder.append('_');
 125  
             }
 126  0
             appendToBuilder(_counterStack.get(_counterStack.size()-1).getCounter(),
 127  
                 _radix, _builder, _bufferConversion);
 128  
         }
 129  
         
 130  0
         _counterStack.add(new Section(_builder.toString(),1,_radix));
 131  0
         _activeSection++;
 132  0
         return _builder.toString();
 133  
     }
 134  
     
 135  
     public String startUniqueIdSection(String base)
 136  
     {
 137  
         //1. Calculate prefix
 138  0
         _builder.delete(0, _builder.length());
 139  
         
 140  0
         if (!_counterStack.isEmpty())
 141  
         {
 142  0
             String lastPrefix = _counterStack.get(_counterStack.size()-1).getPrefix();
 143  0
             if (lastPrefix != null)
 144  
             {
 145  0
                 _builder.append(lastPrefix);
 146  0
                 _builder.append('_');
 147  
             }
 148  0
             appendToBuilder(_counterStack.get(_counterStack.size()-1).getCounter()-1,
 149  
                 _radix, _builder, _bufferConversion);
 150  
         }
 151  
 
 152  0
         if (base != null && base.length() > 0)
 153  
         {
 154  0
             _builder.append('_');
 155  0
             _builder.append(base);
 156  
         }
 157  0
         _counterStack.add(new Section(_builder.toString(),1,_radix));
 158  0
         _activeSection++;
 159  0
         return _builder.toString();
 160  
     }
 161  
 
 162  
     public String generateUniqueId()
 163  
     {
 164  0
         if (_activeSection == 0 && _uniqueIdsCache != null)
 165  
         {
 166  0
             long i = _counterStack.get(_activeSection).getCounter();
 167  0
             if (((int)i) < (long)_uniqueIdsCache.length)
 168  
             {
 169  0
                 _counterStack.get(_activeSection).incrementUniqueId();
 170  0
                 return _uniqueIdsCache[((int)i)-1];
 171  
             }
 172  
             else
 173  
             {
 174  0
                 return _counterStack.get(_activeSection).generateUniqueId(_prefix);
 175  
             }
 176  
         }
 177  
         else
 178  
         {
 179  0
             return _counterStack.get(_activeSection).generateUniqueId(_prefix);
 180  
         }
 181  
     }
 182  
     
 183  
     public void generateUniqueId(StringBuilder builderToAdd)
 184  
     {
 185  0
         _counterStack.get(_activeSection).generateUniqueId(_prefix, builderToAdd);
 186  0
     }
 187  
     
 188  
     public void incrementUniqueId()
 189  
     {
 190  0
         _counterStack.get(_activeSection).incrementUniqueId();
 191  0
     }
 192  
     
 193  
     public void endUniqueIdSection()
 194  
     {
 195  0
         if (_activeSection <= 0)
 196  
         {
 197  0
             _counterStack.get(_activeSection).generateUniqueId(_prefix);
 198  0
             return;
 199  
         }
 200  
         else
 201  
         {
 202  0
             _counterStack.remove(_activeSection);
 203  0
             _activeSection--;
 204  0
             _counterStack.get(_activeSection).generateUniqueId(_prefix);
 205  
         }
 206  0
     }
 207  
     
 208  
     public void endUniqueIdSection(String base)
 209  
     {
 210  0
         if (_activeSection <= 0)
 211  
         {
 212  0
             return;
 213  
         }
 214  
         else
 215  
         {
 216  0
             _counterStack.remove(_activeSection);
 217  0
             _activeSection--;
 218  
         }
 219  0
     }
 220  
     
 221  
     private static class Section
 222  
     {
 223  
         
 224  
         private String prefix;
 225  
         private long counter;
 226  
         private final StringBuilder _builder;
 227  
         private char[] _bufferConversion;
 228  
         private final int _radix;
 229  
         
 230  
         public Section(String prefix, long counter, int radix)
 231  
         {
 232  0
             super();
 233  0
             this.prefix = prefix;
 234  0
             this.counter = counter;
 235  0
             _builder = new StringBuilder(30);
 236  0
             _bufferConversion = new char[15];
 237  0
             _radix = radix;
 238  0
         }
 239  
 
 240  
         public long getCounter()
 241  
         {
 242  0
             return counter;
 243  
         }
 244  
         
 245  
         public void incrementUniqueId()
 246  
         {
 247  0
             this.counter++;
 248  0
         }
 249  
 
 250  
         public void generateUniqueId(String base, StringBuilder builder)
 251  
         {
 252  0
             long i = this.counter;
 253  0
             this.counter++;
 254  
             //_builder.delete(0, _builder.length());
 255  0
             if (base != null)
 256  
             {
 257  0
                 builder.append(base);
 258  
             }
 259  0
             if (this.prefix != null)
 260  
             {
 261  0
                 builder.append(this.prefix);
 262  0
                 builder.append('_');
 263  
             }
 264  
             // By performance reasons, Long.toString is a very expensive
 265  
             // operation in this location, because it triggers a new String()
 266  
             //_builder.append(Long.toString(i, _radix));
 267  0
             appendToBuilder(i, _radix, builder, _bufferConversion);
 268  
             //return _builder.toString();
 269  0
         }
 270  
         
 271  
         public String generateUniqueId(String base)
 272  
         {
 273  0
             long i = this.counter;
 274  0
             this.counter++;
 275  0
             _builder.delete(0, _builder.length());
 276  0
             if (base != null)
 277  
             {
 278  0
                 _builder.append(base);
 279  
             }
 280  0
             if (this.prefix != null)
 281  
             {
 282  0
                 _builder.append(this.prefix);
 283  0
                 _builder.append('_');
 284  
             }
 285  
             // By performance reasons, Long.toString is a very expensive
 286  
             // operation in this location, because it triggers a new String()
 287  
             //_builder.append(Long.toString(i, _radix));
 288  0
             appendToBuilder(i, _radix, _builder, _bufferConversion);
 289  0
             return _builder.toString();
 290  
         }
 291  
 
 292  
         /**
 293  
          * @return the prefix
 294  
          */
 295  
         public String getPrefix()
 296  
         {
 297  0
             return prefix;
 298  
         }
 299  
     }
 300  
     
 301  
     //From Harmony Long.toString(l,radix)
 302  
     private static void appendToBuilder(long l, int radix, StringBuilder builder, char[] bufferConversion)
 303  
     {
 304  0
         if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
 305  
         {
 306  0
             radix = 10;
 307  
         }
 308  0
         if (l == 0)
 309  
         {
 310  0
             builder.append('0');
 311  0
             return;
 312  
         }
 313  
 
 314  0
         int count = 2;
 315  0
         long j = l;
 316  0
         boolean negative = l < 0;
 317  0
         if (!negative)
 318  
         {
 319  0
             count = 1;
 320  0
             j = -l;
 321  
         }
 322  0
         while ((l /= radix) != 0)
 323  
         {
 324  0
             count++;
 325  
         }
 326  
 
 327  0
         if (bufferConversion.length < count)
 328  
         {
 329  0
             bufferConversion = new char[count];
 330  
         }
 331  0
         int finalCount = count;
 332  
 
 333  0
         char[] buffer = bufferConversion;
 334  
         do 
 335  
         {
 336  0
             int ch = 0 - (int) (j % radix);
 337  0
             if (ch > 9)
 338  
             {
 339  0
                 ch = ch - 10 + 'a';
 340  
             }
 341  
             else
 342  
             {
 343  0
                 ch += '0';
 344  
             }
 345  0
             buffer[--count] = (char) ch;
 346  0
             j /= radix;
 347  
         }
 348  0
         while (j != 0);
 349  0
         if (negative)
 350  
         {
 351  0
             buffer[0] = '-';
 352  
         }
 353  0
         for (int i = 0; i < finalCount; i++)
 354  
         {
 355  0
             builder.append(buffer[i]);
 356  
         }
 357  
         //return new String(0, buffer.length, buffer);
 358  0
     }
 359  
 }