Coverage Report - yarfraw.io.FeedAppender
 
Classes in this File Line Coverage Branch Coverage Complexity
FeedAppender
83% 
100% 
0
 
 1  
 package yarfraw.io;
 2  
 
 3  
 import java.io.File;
 4  
 import java.net.URI;
 5  
 import java.util.ArrayList;
 6  
 import java.util.Arrays;
 7  
 import java.util.List;
 8  
 
 9  
 import org.apache.commons.collections.CollectionUtils;
 10  
 
 11  
 import yarfraw.core.datamodel.ChannelFeed;
 12  
 import yarfraw.core.datamodel.FeedFormat;
 13  
 import yarfraw.core.datamodel.ItemEntry;
 14  
 import yarfraw.core.datamodel.YarfrawException;
 15  
 /**
 16  
  * Provides a set of function to facilitate modifications to an RSS 2.0 feed.
 17  
  * <br/>
 18  
  * *Note* This class is not thread safe.
 19  
  * @author jliang
 20  
  *
 21  
  */
 22  
 public class FeedAppender{
 23  
   private FeedWriter _writer;
 24  
   private FeedReader _reader;
 25  12
   private int _numItemToKeep = -1;
 26  
 
 27  12
   public FeedAppender(File file, FeedFormat format) {
 28  12
     _writer = new FeedWriter(file);
 29  12
     _reader = new FeedReader(file);
 30  12
     setFormat(format);
 31  12
   }
 32  
   public FeedAppender(String pathName, FeedFormat format){
 33  0
     this(new File(pathName), format);
 34  0
   }
 35  
   
 36  
   public FeedAppender(URI uri, FeedFormat format){
 37  0
     this(new File(uri), format);
 38  0
   }
 39  
   
 40  
   public FeedAppender(File file) {
 41  9
     this(file, FeedFormat.RSS20);
 42  9
   }
 43  
   public FeedAppender(String pathName){
 44  3
     this(new File(pathName), FeedFormat.RSS20);
 45  3
   }
 46  
   
 47  
   public FeedAppender(URI uri){
 48  0
     this(new File(uri), FeedFormat.RSS20);
 49  0
   } 
 50  
   
 51  
 
 52  
   /**
 53  
    * The {@link FeedFormat} this writer should be using.<br/>
 54  
    * if this is not set, the default is RSS 2.0 format. <code>null</code> format is ignored  
 55  
    * @return a {@link FeedFormat} enum
 56  
    */
 57  
   public FeedFormat getFormat() {
 58  9
     return _reader.getFormat();
 59  
   }
 60  
 
 61  
   /**
 62  
    * The {@link FeedFormat} this writer should be using.<br/>
 63  
    * if this is not set, the default is RSS 2.0 format. <code>null</code> format is ignored  
 64  
    * @param format a {@link FeedFormat} enum
 65  
    */
 66  
   public void setFormat(FeedFormat format) {
 67  18
     if(format != null){
 68  18
       _reader.setFormat(format);
 69  18
       _writer.setFormat(format);
 70  
     } 
 71  18
   }
 72  
 
 73  
   /**
 74  
    * Maximum number of items to keep in a feed. If the number of actual items
 75  
    * If <code>numItemToKeep</code> is non-negative and the actual number of {@link ItemEntry} (after appends)
 76  
    * in the feed greater than <code>numItemToKeep</code>, the appender will remove items from the END
 77  
    * of the feed to ensure there is at most <code>numItemToKeep</code> items in the feed.
 78  
    * @return the current <code>numberItemToKepp</code>, -1 if the value has not yet been set or there's no limit.
 79  
    */
 80  
   public int getNumItemToKeep() {
 81  3
     return _numItemToKeep;
 82  
   }
 83  
 
 84  
   /**
 85  
    * Maximum number of items to keep in a feed. If the number of actual items
 86  
    * If <code>numItemToKeep</code> is non-negative and the actual number of {@link ItemEntry} (after appends)
 87  
    * in the feed greater than <code>numItemToKeep</code>, the appender will remove items from the END
 88  
    * of the feed to ensure there is at most <code>numItemToKeep</code> items in the feed.   
 89  
    * @param numItemToKeep number of items to keep in the current feed. no limit if it's negative.
 90  
    * @return this
 91  
    */
 92  
   public FeedAppender setNumItemToKeep(int numItemToKeep) {
 93  9
     _numItemToKeep = numItemToKeep < 0 ? -1 : numItemToKeep;
 94  9
     return this;
 95  
   }
 96  
     
 97  
   private List<ItemEntry> trimItemsList(List<ItemEntry> items){
 98  24
     if(_numItemToKeep != -1 && CollectionUtils.isNotEmpty(items)
 99  
             && items.size() > _numItemToKeep){
 100  18
       return items.subList(0, _numItemToKeep);
 101  
     }
 102  6
     return items;
 103  
   }
 104  
 
 105  
   /**
 106  
    * Appends all of the {@link ItemEntry} in the specified collection into the current feed
 107  
    * at the specified position (optional operation).  Shifts the
 108  
    * {@link ItemEntry} currently at that position (if any) and any subsequent
 109  
    * {@link ItemEntry} to the right (increases their indices).
 110  
    * <br/>
 111  
    * As in  <code>feedItemList.addAll(index, inputlist)</code>
 112  
    * <br/>
 113  
    * If <code>numItemToKeep</code> is set and the resulting number of {@link ItemEntry} (after the append)
 114  
    * in the feed greater than <code>numItemToKeep</code>, the appender will remove items from the END
 115  
    * of the feed to ensure there is at most <code>numItemToKeep</code> items in the feed.
 116  
    * 
 117  
    * @param index index to append to
 118  
    * @param items any number of {@link yarfraw.core.datamodel.ItemEntry}
 119  
    * @return this
 120  
    * @throws YarfrawException if operation failed.
 121  
    */
 122  
   public FeedAppender appendAllItemsAt(int index, List<ItemEntry> items) throws YarfrawException{
 123  15
     ChannelFeed ch = readChannel();
 124  15
     List<ItemEntry> old = ch.getItems();
 125  15
     if(old == null){
 126  0
       old = new ArrayList<ItemEntry>();
 127  0
       ch.setItems(old);
 128  
     }
 129  15
     old.addAll(index, items);
 130  15
     ch.setItems(trimItemsList(old));
 131  15
     _writer = new FeedWriter(_reader._file);
 132  15
     _writer.writeChannel(ch);
 133  15
     return this;
 134  
   }
 135  
   
 136  
   /**
 137  
    * Appends all of the {@link ItemEntry} to the <b>beginning</b> of the item list in  the current feed.
 138  
    * Shifts the {@link ItemEntry} currently at that position (if any) and any subsequent
 139  
    * {@link ItemEntry} to the right (increases their indices).
 140  
    * <br/>
 141  
    * This is equivalent to <code>appendAllItemsAt(0, inputlist)</code>
 142  
    * <br/>
 143  
    * If <code>numItemToKeep</code> is set and the resulting number of {@link ItemEntry} (after the append)
 144  
    * in the feed greater than <code>numItemToKeep</code>, the appender will remove items from the END
 145  
    * of the feed to ensure there is at most <code>numItemToKeep</code> items in the feed.
 146  
    *
 147  
    * @param items
 148  
    * @return
 149  
    * @throws YarfrawException if the appender failed to read or write the feed file.
 150  
    */
 151  
   public FeedAppender appendAllItemsToBeginning(List<ItemEntry> items) throws YarfrawException{
 152  15
     return appendAllItemsAt(0, items);
 153  
   }
 154  
   
 155  
   /**
 156  
    * Appends all of the {@link ItemEntry} to the <b>beginning</b> of the item list in the current feed.
 157  
    * Shifts the {@link ItemEntry} currently at that position (if any) and any subsequent
 158  
    * {@link ItemEntry} to the right (increases their indices).
 159  
    * <br/>
 160  
    * This is equivalent to <code>appendAllItemsAt(0, Arrays.asList(item1, item2, item3))</code>
 161  
    * <br/>
 162  
    * If <code>numItemToKeep</code> is set and the resulting number of {@link ItemEntry} (after the append)
 163  
    * in the feed greater than <code>numItemToKeep</code>, the appender will remove items from the END
 164  
    * of the feed to ensure there is at most <code>numItemToKeep</code> items in the feed.
 165  
    *
 166  
    * @param items
 167  
    * @return
 168  
    * @throws YarfrawException if the appender failed to read or write the feed file.
 169  
    */
 170  
   public FeedAppender appendAllItemsToBeginning(ItemEntry...items) throws YarfrawException{
 171  9
     return appendAllItemsToBeginning(Arrays.asList(items));
 172  
   }
 173  
   
 174  
 
 175  
   /**
 176  
    * Appends all of the {@link ItemEntry} to the <b>end</b> of the item list in current feed.
 177  
    * Shifts the {@link ItemEntry} currently at that position (if any) and any subsequent
 178  
    * {@link ItemEntry} to the right (increases their indices).
 179  
    * <br/>
 180  
    * If <code>numItemToKeep</code> is set and the resulting number of {@link ItemEntry} (after the append)
 181  
    * in the feed greater than <code>numItemToKeep</code>, the appender will remove items from the END
 182  
    * of the feed to ensure there is at most <code>numItemToKeep</code> items in the feed.
 183  
    *
 184  
    * @param items
 185  
    * @return
 186  
    * @throws YarfrawException if the appender failed to read or write the feed file.
 187  
    */
 188  
   public FeedAppender appendAllItemsToEnd(List<ItemEntry> items) throws YarfrawException{
 189  6
     ChannelFeed ch = readChannel();
 190  6
     List<ItemEntry> old = ch.getItems();
 191  6
     if(old == null){
 192  0
       old = new ArrayList<ItemEntry>();
 193  0
       ch.setItems(old);
 194  
     }
 195  6
     old.addAll(items);
 196  6
     ch.setItems(trimItemsList(old));
 197  6
     _writer = new FeedWriter(_reader._file);
 198  6
     _writer.writeChannel(ch);
 199  6
     return this;
 200  
   }
 201  
 
 202  
   /**
 203  
    * Appends all of the {@link ItemEntry} to the <b>end</b> of the item list in the current feed.
 204  
    * Shifts the {@link ItemEntry} currently at that position (if any) and any subsequent
 205  
    * {@link ItemEntry} to the right (increases their indices).
 206  
    * <br/>
 207  
    * If <code>numItemToKeep</code> is set and the resulting number of {@link ItemEntry} (after the append)
 208  
    * in the feed greater than <code>numItemToKeep</code>, the appender will remove items from the END
 209  
    * of the feed to ensure there is at most <code>numItemToKeep</code> items in the feed.
 210  
    *
 211  
    * @param items
 212  
    * @return
 213  
    * @throws YarfrawException if the appender failed to read or write the feed file.
 214  
    */
 215  
   public FeedAppender appendAllItemsToEnd(ItemEntry...items) throws YarfrawException{
 216  3
     return appendAllItemsToEnd(Arrays.asList(items));
 217  
   }
 218  
 
 219  
   /**
 220  
    * * Remove the item at index <code>index</code> from the feed.
 221  
    * @param index
 222  
    * @return
 223  
    * @throws YarfrawException if the appender failed to read or write the feed file.
 224  
    */
 225  
   public FeedAppender removeItem(int index) throws YarfrawException{
 226  3
     ChannelFeed ch = readChannel();
 227  3
     ch.getItems().remove(index);
 228  3
     ch.setItems(trimItemsList(ch.getItems()));
 229  3
     _writer.writeChannel(ch);
 230  3
     return this;
 231  
   }
 232  
 
 233  
   /**
 234  
    * Set the item at index <code>index</code> to be the input <code>item</code>
 235  
    * @param index
 236  
    * @param item
 237  
    * @return
 238  
    * @throws YarfrawException if the appender failed to read or write the feed file.
 239  
    */
 240  
   public FeedAppender setItem(int index, ItemEntry item) throws YarfrawException{
 241  6
     ChannelFeed ch = readChannel();
 242  6
     ch.getItems().set(index, item);
 243  6
     _writer.writeChannel(ch);
 244  6
     return this;
 245  
   }
 246  
   
 247  
   private ChannelFeed readChannel() throws YarfrawException{
 248  30
     ChannelFeed ch = _reader.readChannel(); 
 249  30
     if(ch.getItems() == null){
 250  0
       ch.setItems(new ArrayList<ItemEntry>());
 251  
     }
 252  30
     return ch;
 253  
   }
 254  
 }