1   package com.github.triceo.splitlog;
2   
3   import java.util.Collection;
4   import java.util.Collections;
5   import java.util.LinkedList;
6   import java.util.List;
7   import java.util.concurrent.atomic.AtomicLong;
8   
9   import com.github.triceo.splitlog.api.Message;
10  import com.github.triceo.splitlog.api.TailSplitter;
11  import com.github.triceo.splitlog.splitters.SimpleTailSplitter;
12  
13  final class MessageBuilder {
14  
15      private static final TailSplitter DEFAULT_TAIL_SPLITTER = new SimpleTailSplitter();
16      private static final AtomicLong MESSAGE_ID_GENERATOR = new AtomicLong(0);
17      private static final long NO_MESSAGE_ID_SET = -1;
18  
19      private long futureMessageId = MessageBuilder.NO_MESSAGE_ID_SET;
20      private final List<String> lines = new LinkedList<String>();
21      private Message previousMessage;
22      private long timestamp;
23  
24      
25  
26  
27  
28  
29  
30  
31      public MessageBuilder(final String firstLine) {
32          if (firstLine == null) {
33              throw new IllegalArgumentException("First line may not be null.");
34          }
35          this.timestamp = System.currentTimeMillis();
36          this.add(firstLine);
37      }
38  
39      
40  
41  
42  
43  
44  
45  
46      public synchronized MessageBuilder add(final Collection<String> lines) {
47          this.lines.addAll(lines);
48          return this;
49      }
50  
51      
52  
53  
54  
55  
56  
57  
58      public MessageBuilder add(final String line) {
59          return this.add(Collections.singletonList(line));
60      }
61  
62      public Message buildFinal() {
63          return this.buildFinal(MessageBuilder.DEFAULT_TAIL_SPLITTER);
64      }
65  
66      public synchronized Message buildFinal(final TailSplitter splitter) {
67          if (this.futureMessageId == MessageBuilder.NO_MESSAGE_ID_SET) {
68              
69              this.futureMessageId = MessageBuilder.MESSAGE_ID_GENERATOR.getAndIncrement();
70          }
71          final Message msg = new DefaultMessage(this.futureMessageId, this.getLines(), this.getTimestamp(), splitter,
72                  this.previousMessage);
73          
74          this.futureMessageId = MessageBuilder.NO_MESSAGE_ID_SET;
75          return msg;
76      }
77  
78      public Message buildIntermediate() {
79          return this.buildIntermediate(MessageBuilder.DEFAULT_TAIL_SPLITTER);
80      }
81  
82      public synchronized Message buildIntermediate(final TailSplitter splitter) {
83          if (this.futureMessageId == MessageBuilder.NO_MESSAGE_ID_SET) {
84              
85              this.futureMessageId = MessageBuilder.MESSAGE_ID_GENERATOR.getAndIncrement();
86          }
87          return new DefaultMessage(this.futureMessageId, this.getLines(), this.getTimestamp(), splitter,
88                  this.previousMessage);
89      }
90  
91      public synchronized Message buildTag() {
92          if (this.futureMessageId == MessageBuilder.NO_MESSAGE_ID_SET) {
93              
94              this.futureMessageId = MessageBuilder.MESSAGE_ID_GENERATOR.getAndIncrement();
95          }
96          final Message msg = new DefaultMessage(this.futureMessageId, this.getFirstLine());
97          
98          this.futureMessageId = MessageBuilder.NO_MESSAGE_ID_SET;
99          return msg;
100     }
101 
102     
103 
104 
105 
106     private String getFirstLine() {
107         return this.lines.get(0);
108     }
109 
110     
111 
112 
113 
114 
115     private synchronized List<String> getLines() {
116         return Collections.unmodifiableList(new LinkedList<String>(this.lines));
117     }
118 
119     public Message getPreviousMessage() {
120         return this.previousMessage;
121     }
122 
123     public long getTimestamp() {
124         return this.timestamp;
125     }
126 
127     public MessageBuilder setPreviousMessage(final Message previousMessage) {
128         this.previousMessage = previousMessage;
129         return this;
130     }
131 
132     
133 
134 
135 
136 
137 
138 
139 
140     public MessageBuilder setTimestamp(final long timestamp) {
141         this.timestamp = timestamp;
142         return this;
143     }
144 
145 }