LazyStringBuilder.java

  1. /**
  2.  *
  3.  * Copyright 2014 Florian Schmaus
  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. package org.jivesoftware.smack.util;

  18. import java.util.ArrayList;
  19. import java.util.List;

  20. public class LazyStringBuilder implements Appendable, CharSequence {

  21.     private final List<CharSequence> list;

  22.     private String cache;

  23.     private void invalidateCache() {
  24.         cache = null;
  25.     }

  26.     public LazyStringBuilder() {
  27.         list = new ArrayList<CharSequence>(20);
  28.     }

  29.     public LazyStringBuilder append(LazyStringBuilder lsb) {
  30.         list.addAll(lsb.list);
  31.         invalidateCache();
  32.         return this;
  33.     }

  34.     @Override
  35.     public LazyStringBuilder append(CharSequence csq) {
  36.         assert csq != null;
  37.         list.add(csq);
  38.         invalidateCache();
  39.         return this;
  40.     }

  41.     @Override
  42.     public LazyStringBuilder append(CharSequence csq, int start, int end) {
  43.         CharSequence subsequence = csq.subSequence(start, end);
  44.         list.add(subsequence);
  45.         invalidateCache();
  46.         return this;
  47.     }

  48.     @Override
  49.     public LazyStringBuilder append(char c) {
  50.         list.add(Character.toString(c));
  51.         invalidateCache();
  52.         return this;
  53.     }

  54.     @Override
  55.     public int length() {
  56.         if (cache != null) {
  57.             return cache.length();
  58.         }
  59.         int length = 0;
  60.         for (CharSequence csq : list) {
  61.             length += csq.length();
  62.         }
  63.         return length;
  64.     }

  65.     @Override
  66.     public char charAt(int index) {
  67.         if (cache != null) {
  68.             return cache.charAt(index);
  69.         }
  70.         for (CharSequence csq : list) {
  71.             if (index < csq.length()) {
  72.                 return csq.charAt(index);
  73.             } else {
  74.                 index -= csq.length();
  75.             }
  76.         }
  77.         throw new IndexOutOfBoundsException();
  78.     }

  79.     @Override
  80.     public CharSequence subSequence(int start, int end) {
  81.         return toString().subSequence(start, end);
  82.     }

  83.     @Override
  84.     public String toString() {
  85.         if (cache == null) {
  86.             StringBuilder sb = new StringBuilder(length());
  87.             for (CharSequence csq : list) {
  88.                 sb.append(csq);
  89.             }
  90.             cache = sb.toString();
  91.         }
  92.         return cache;
  93.     }
  94. }