001package votorola.s.gwt.scene.feed.ss; // Copyright 2011-2012, Michael Allan, Christian Weilbach.  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE.
002
003import com.google.gson.stream.JsonWriter;
004import java.io.IOException;
005import java.util.*;
006import votorola.g.util.ArrayListX;
007
008import static votorola.g.util.ArrayListX.EMPTY_LIST;
009
010
011/** A serial jig for a bite.
012  */
013public final class BiteJig implements votorola.s.gwt.scene.feed.Bite, SerialJig
014{
015
016    // adding fields?  ensure they are cleared in serialize()
017
018
019    /** Removes all persons from the specified list and caches them for reuse.
020      *
021      *     @see #uncachePerson()
022      */
023    void encachePersons( ArrayList<PersonJig> persons ) { encachePersons( persons, 0 ); }
024
025
026        private ArrayList<PersonJig> personCache = ArrayListX.emptyList(); // i.e. EMPTY_LIST
027
028
029        /** Removes all persons from the specified list and caches the persons from
030          * the start onwards for reuse.
031          *
032          *     @see #uncachePerson()
033          */
034        void encachePersons( final ArrayList<PersonJig> persons, final int start )
035        {
036            for( int p = start, pN = persons.size(); p < pN; ++p )
037            {
038                personCache.add( persons.get( p ));
039            }
040            persons.clear();
041        }
042
043
044
045    /** Fetches a person jig from the cache, or creates a new jig if the cache is
046      * empty.
047      *
048      *     @see #encachePersons(ArrayList)
049      */
050    PersonJig uncachePerson()
051    {
052        if( personCache == EMPTY_LIST )
053        {
054            personCache = new ArrayList<PersonJig>( /*initial capacity*/20 ); // lots for PersonJig's vote traces
055        }
056
057        return personCache.size() > 0? personCache.remove(0): new PersonJig(BiteJig.this);
058    }
059
060
061
062   // - B i t e --------------------------------------------------------------------------
063
064
065    public DiffLookJig difference() { return difference; }
066
067
068        private DiffLookJig difference;
069
070
071        private void difference( final JsonWriter out ) throws IOException
072        {
073            if( difference == null ) return;
074
075            out.name( "difference" );
076            difference.serialize( out );
077            difference = null;
078        }
079
080
081        private DiffLookJig differenceC;
082
083
084        /** Ensures the difference is set to a jig and caches the jig for reuse.
085          *
086          *     @return the jig that was set.
087          */
088        public DiffLookJig setDifference()
089        {
090            if( differenceC == null ) differenceC = new DiffLookJig();
091
092            difference = differenceC;
093            return differenceC;
094        }
095
096
097
098    public MessageJig message() { return messages.size() == 0? null: messages.get( 0 ); }
099
100
101
102    public List<MessageJig> messages() { return messages; }
103
104
105        private ArrayList<MessageJig> messages = ArrayListX.emptyList(); // i.e. EMPTY_LIST
106
107
108        private void messages( final JsonWriter out ) throws IOException
109        {
110            if( messages.size() == 0 ) return; // that is the default in BiteJS
111
112            out.name( "messages" );
113            out.beginArray();
114            for( MessageJig jig: messages ) jig.serialize( out );
115            out.endArray();
116            messagesC.addAll( messages );
117            messages.clear();
118        }
119
120
121        private ArrayList<MessageJig> messagesC = messages;
122
123
124        /** Adds a message jig, caching it for reuse.
125          *
126          *     @return the jig added.
127          */
128        public MessageJig addMessage()
129        {
130            if( messages == EMPTY_LIST )
131            {
132                messages = new ArrayList<MessageJig>( /*initial capacity*/1 );
133                messagesC = new ArrayList<MessageJig>( /*initial capacity*/1 );
134            }
135
136            final MessageJig jig;
137            if( messagesC.size() > 0 ) jig = messagesC.remove( 0 );
138            else jig = new MessageJig();
139
140            messages.add( jig );
141            return jig;
142        }
143
144    public char relation() { return relation; }
145
146        private char relation = ' ';
147
148        private void relation( final JsonWriter out ) throws IOException
149        {
150            if( relation == ' ' ) return;
151
152            out.name("relation").value( relation );
153            relation = ' ';
154        }
155
156        /** Sets the relation of the first person to the other
157         * in difference related messages.
158          */
159        public void setRelation( final char c ) { relation = c; } 
160
161
162    public Date sentDate() { return sentDate; }
163
164
165        private Date sentDate = null;
166
167
168        private void sentDate( final JsonWriter out ) throws IOException
169        {
170            if( sentDate == null ) return;
171
172            out.name( "sentDate" ).value( sentDate.getTime() );
173            sentDate = null;
174        }
175
176
177        /** Sets the date on which the bite was parsed.
178          */
179        public void setSentDate( final Date pd ) { sentDate = pd; } // OPT a single Date instance should be cached for reuse; or better yet it should be a long
180
181
182
183    public PersonJig person() { return persons.size() == 0? null: persons.get( 0 ); }
184
185
186
187    public List<PersonJig> persons() { return persons; }
188
189
190        private ArrayList<PersonJig> persons = ArrayListX.emptyList(); // i.e. EMPTY_LIST
191
192
193        private void persons( final JsonWriter out ) throws IOException
194        {
195            if( persons.size() == 0 ) return; // that is the default in BiteJS
196
197            out.name( "persons" );
198            out.beginArray();
199            for( PersonJig jig: persons ) jig.serialize( out );
200            out.endArray();
201            encachePersons( persons );
202        }
203
204
205        /** Adds a person jig, caching it for reuse.
206          *
207          *     @return the jig added.
208          */
209        public PersonJig addPerson()
210        {
211            if( persons == EMPTY_LIST ) persons = new ArrayList<PersonJig>( /*initial capacity*/2 );
212
213            final PersonJig jig = uncachePerson();
214            persons.add( jig );
215            return jig;
216        }
217
218
219
220    public PollJig poll() { return poll; }
221
222
223        private PollJig poll;
224
225
226        private void poll( final JsonWriter out ) throws IOException
227        {
228            if( poll == null ) return;
229
230            out.name( "poll" );
231            poll.serialize( out );
232            poll = null;
233        }
234
235
236        private PollJig pollC;
237
238
239        /** Ensures the poll is set to a jig and caches the jig for reuse.
240          *
241          *     @return the jig that was set.
242          */
243        public PollJig setPoll()
244        {
245            if( pollC == null ) pollC = new PollJig();
246
247            poll = pollC;
248            return pollC;
249        }
250
251
252
253   // - S e r i a l - J i g --------------------------------------------------------------
254
255
256    public void serialize( final JsonWriter out ) throws IOException
257    {
258        out.beginObject();
259
260        difference( out );
261        messages( out );
262        relation( out );
263        sentDate( out );
264        persons( out );
265        poll( out );
266
267        out.endObject();
268    }
269
270}