001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package org.apache.geronimo.javamail.store.nntp.newsrc;
021    
022    import java.io.IOException;
023    import java.io.Writer;
024    
025    public class NNTPNewsrcGroup {
026        // the newsrc database we're part of
027        NNTPNewsrc newsrc;
028    
029        // the name of the group
030        protected String name;
031    
032        // the subscription flage
033        protected boolean subscribed;
034    
035        // the range of already seen articles.
036        protected RangeList ranges;
037    
038        /**
039         * Construct a NNTPNewsrcGroup item associated with a given .newsrc
040         * database.
041         * 
042         * @param newsrc
043         *            The owning .newsrc database.
044         * @param line
045         *            The .newsrc range entries in .newsrc format. These ranges are
046         *            parsed to create a set of seen flags.
047         * 
048         * @return A created NNTPNewsrcGroup item.
049         */
050        public static NNTPNewsrcGroup parse(NNTPNewsrc newsrc, String line) {
051            String groupName = null;
052            String ranges = null;
053    
054            // subscribed lines have a ':' marker acting as a delimiter
055            int marker = line.indexOf(':');
056    
057            if (marker != -1) {
058                groupName = line.substring(0, marker);
059                ranges = line.substring(marker + 1);
060                return new NNTPNewsrcGroup(newsrc, groupName, ranges, true);
061            }
062    
063            // now check for an unsubscribed group
064            marker = line.indexOf('!');
065    
066            if (marker != -1) {
067                groupName = line.substring(0, marker);
068                ranges = line.substring(marker + 1);
069                return new NNTPNewsrcGroup(newsrc, groupName, ranges, false);
070            }
071    
072            // must be a comment line
073            return null;
074        }
075    
076        /**
077         * Construct a .newsrc group item.
078         * 
079         * @param newsrc
080         *            The owning newsrc database.
081         * @param name
082         *            The group name.
083         * @param newsrcRanges
084         *            The initial set of seen ranges for the group (may be null).
085         * @param subscribed
086         *            The initial group subscription state.
087         */
088        public NNTPNewsrcGroup(NNTPNewsrc newsrc, String name, String newsrcRanges, boolean subscribed) {
089            this.newsrc = newsrc;
090            this.name = name;
091            this.subscribed = subscribed;
092            this.ranges = new RangeList(newsrcRanges);
093        }
094    
095        /**
096         * Get the group name.
097         * 
098         * @return The String name of the group.
099         */
100        public String getName() {
101            return name;
102        }
103    
104        /**
105         * Get the newsrc subscribed status for an article.
106         * 
107         * @return The current subscription flag.
108         */
109        public boolean isSubscribed() {
110            return subscribed;
111        }
112    
113        /**
114         * Set the subscription status for an article.
115         * 
116         * @param flag
117         *            The new subscription value.
118         */
119        public void setSubscribed(boolean flag) {
120            // we don't blindly set this to the new value since we only want to
121            // resave the newsrc file if
122            // something changes.
123            if (flag && !subscribed) {
124                subscribed = true;
125                newsrc.setDirty();
126            } else if (!flag && subscribed) {
127                subscribed = false;
128                newsrc.setDirty();
129            }
130        }
131    
132        /**
133         * Test if an article has been seen yet.
134         * 
135         * @param article
136         *            The target article.
137         * 
138         * @return The seen mark for the article.
139         */
140        public boolean isArticleSeen(int article) {
141            return ranges.isMarked(article);
142        }
143    
144        /**
145         * Mark an article as seen.
146         * 
147         * @param article
148         *            The target article number.
149         */
150        public void markArticleSeen(int article) {
151            ranges.setMarked(article);
152            if (ranges.isDirty()) {
153                newsrc.setDirty();
154            }
155        }
156    
157        /**
158         * Mark an article as unseen.
159         * 
160         * @param article
161         *            The target article number.
162         */
163        public void markArticleUnseen(int article) {
164            ranges.setUnmarked(article);
165            if (ranges.isDirty()) {
166                newsrc.setDirty();
167            }
168        }
169    
170        /**
171         * Save this group definition to a .newsrc file.
172         * 
173         * @param out
174         *            The output writer to send the information to.
175         * 
176         * @exception IOException
177         */
178        public void save(Writer out) throws IOException {
179            out.write(name);
180            out.write(subscribed ? ": " : "! ");
181            ranges.save(out);
182            // put a terminating line end
183            out.write("\r\n");
184        }
185    }