File Source: authorindex.java
1 /*
2 * Copyright (c) 2003-2006, Simon Brown
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * - Neither the name of Pebble nor the names of its contributors may
17 * be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32 package net.sourceforge.pebble.index;
33
34 import net.sourceforge.pebble.comparator.ReverseBlogEntryIdComparator;
35 import net.sourceforge.pebble.domain.Blog;
36 import net.sourceforge.pebble.domain.BlogEntry;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40 import java.io.*;
41 import java.util.*;
42
43 /**
44 * Keeps an index of all blog entries from a specific author, allowing efficient access at runtime.
45 *
46 * @author Simon Brown
47 */
48 public class AuthorIndex {
49
/*
P/P * Method: net.sourceforge.pebble.index.AuthorIndex__static_init
*
* Postconditions:
* init'ed(log)
*/
50 private static final Log log = LogFactory.getLog(AuthorIndex.class);
51
52 private Blog blog;
53
54 /** the map containing the tags */
55 private Map<String,List<String>> authors = new HashMap<String,List<String>>();
56
/*
P/P * Method: void net.sourceforge.pebble.index.AuthorIndex(Blog)
*
* Preconditions:
* blog != null
*
* Postconditions:
* this.authors == &new HashMap(AuthorIndex#1)
* this.blog == blog
* this.blog != null
* new HashMap(AuthorIndex#1) num objects == 1
*/
57 public AuthorIndex(Blog blog) {
58 this.blog = blog;
59
60 readIndex();
61 }
62
63 /**
64 * Clears the index.
65 */
66 public void clear() {
/*
P/P * Method: void clear()
*
* Preconditions:
* (soft) this.blog != null
*
* Postconditions:
* this.authors == &new HashMap(clear#1)
* new HashMap(clear#1) num objects == 1
*/
67 authors = new HashMap<String,List<String>>();
68 writeIndex();
69 }
70
71 /**
72 * Indexes one or more blog entries.
73 *
74 * @param blogEntries a List of BlogEntry instances
75 */
76 public synchronized void index(Collection<BlogEntry> blogEntries) {
/*
P/P * Method: void index(Collection)
*
* Preconditions:
* blogEntries != null
* (soft) net.sourceforge.pebble.domain.State__static_init.new State(State__static_init#5).name != null
* (soft) this.authors != null
* (soft) this.blog != null
*
* Presumptions:
* blogEntry.state@77 != null
* java.util.Iterator:next(...)@77 != null
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@77: {1}, {0}
*/
77 for (BlogEntry blogEntry : blogEntries) {
78 if (blogEntry.isPublished()) {
79 List<String> blogEntryIds = getBlogEntries(blogEntry.getAuthor());
80 blogEntryIds.add(blogEntry.getId());
81 Collections.sort(blogEntryIds, new ReverseBlogEntryIdComparator());
82 }
83 }
84
85 writeIndex();
86 }
87
88 /**
89 * Indexes a single blog entry.
90 *
91 * @param blogEntry a BlogEntry instance
92 */
93 public synchronized void index(BlogEntry blogEntry) {
/*
P/P * Method: void index(BlogEntry)
*
* Preconditions:
* blogEntry != null
* blogEntry.state != null
* (soft) init'ed(blogEntry.author)
* (soft) init'ed(blogEntry.id)
* (soft) init'ed(blogEntry.state.name)
* (soft) net.sourceforge.pebble.domain.State__static_init.new State(State__static_init#5).name != null
* (soft) this.authors != null
* (soft) this.blog != null
*/
94 if (blogEntry.isPublished()) {
95 List<String> blogEntryIds = getBlogEntries(blogEntry.getAuthor());
96 blogEntryIds.add(blogEntry.getId());
97 Collections.sort(blogEntryIds, new ReverseBlogEntryIdComparator());
98
99 writeIndex();
100 }
101 }
102
103 /**
104 * Unindexes a single blog entry.
105 *
106 * @param blogEntry a BlogEntry instance
107 */
108 public synchronized void unindex(BlogEntry blogEntry) {
/*
P/P * Method: void unindex(BlogEntry)
*
* Preconditions:
* blogEntry != null
* init'ed(blogEntry.author)
* this.authors != null
* (soft) init'ed(blogEntry.id)
* (soft) this.blog != null
*
* Test Vectors:
* java.util.List:isEmpty(...)@113: {0}, {1}
* java.util.Map:get(...)@109: Addr_Set{null}, Inverse{null}
*/
109 List<String> blogEntries = authors.get(blogEntry.getAuthor());
110 if (blogEntries != null) {
111 blogEntries.remove(blogEntry.getId());
112
113 if (blogEntries.isEmpty()) {
114 authors.remove(blogEntry.getAuthor());
115 }
116 }
117
118 writeIndex();
119 }
120
121 /**
122 * Helper method to load the index.
123 */
124 private void readIndex() {
/*
P/P * Method: void readIndex()
*
* Preconditions:
* this.blog != null
* (soft) this.authors != null
*
* Presumptions:
* blogEntryIds.length@136 <= 232-1
* org.apache.commons.logging.LogFactory:getLog(...)@50 != null
* tuple.length@131 >= 1
*
* Test Vectors:
* java.io.File:exists(...)@126: {0}, {1}
* tuple.length@131: {1}, {2..+Inf}
* tuple[1]@131: Addr_Set{null}, Inverse{null}
*/
125 File indexFile = new File(blog.getIndexesDirectory(), "authors.index");
126 if (indexFile.exists()) {
127 try {
128 BufferedReader reader = new BufferedReader(new FileReader(indexFile));
129 String indexEntry = reader.readLine();
130 while (indexEntry != null) {
131 String[] tuple = indexEntry.split("=");
132 String author = tuple[0];
133 List<String> blogEntries = getBlogEntries(author);
134
135 if (tuple.length > 1 && tuple[1] != null) {
136 String[] blogEntryIds = tuple[1].split(",");
137 for (String blogEntry : blogEntryIds) {
138 blogEntries.add(blogEntry);
139 }
140 }
141
142 indexEntry = reader.readLine();
143 }
144
145 reader.close();
146 } catch (Exception e) {
147 log.error("Error while reading index", e);
148 }
149 }
150 }
151
152 /**
153 * Helper method to write out the index to disk.
154 */
155 private void writeIndex() {
156 try {
/*
P/P * Method: void writeIndex()
*
* Preconditions:
* (soft) this.authors != null
* (soft) this.blog != null
*
* Presumptions:
* java.util.Map:keySet(...)@160 != null
* org.apache.commons.logging.LogFactory:getLog(...)@50 != null
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@160: {1}, {0}
* java.util.Iterator:hasNext(...)@165: {1}, {0}
* java.util.Map:get(...)@163: Addr_Set{null}, Inverse{null}
*/
157 File indexFile = new File(blog.getIndexesDirectory(), "authors.index");
158 BufferedWriter writer = new BufferedWriter(new FileWriter(indexFile));
159
160 for (String author : authors.keySet()) {
161 writer.write(author);
162 writer.write("=");
163 List<String> blogEntries = authors.get(author);
164 if (blogEntries != null) {
165 for (String blogEntry : blogEntries) {
166 writer.write(blogEntry);
167 writer.write(",");
168 }
169 }
170 writer.newLine();
171 }
172
173 writer.flush();
174 writer.close();
175 } catch (Exception e) {
176 log.error("Error while writing index", e);
177 }
178 }
179
180 private synchronized List<String> getBlogEntries(String author) {
/*
P/P * Method: List getBlogEntries(String)
*
* Preconditions:
* this.authors != null
*
* Postconditions:
* return_value != null
* new LinkedList(getBlogEntries#1) num objects <= 1
*
* Test Vectors:
* java.util.Map:get(...)@181: Inverse{null}, Addr_Set{null}
*/
181 List<String> blogEntries = authors.get(author);
182 if (blogEntries == null) {
183 blogEntries = new LinkedList<String>();
184 authors.put(author, blogEntries);
185 }
186
187 return blogEntries;
188 }
189
190 /**
191 * Gets the list of authors associated with this blog.
192 */
193 public List<String> getAuthors() {
/*
P/P * Method: List getAuthors()
*
* Preconditions:
* this.authors != null
*
* Postconditions:
* return_value == &new LinkedList(getAuthors#1)
* new LinkedList(getAuthors#1) num objects == 1
*/
194 return new LinkedList<String>(authors.keySet());
195 }
196
197 /**
198 * Gets the blog entries for a given author.
199 *
200 * @param username a username (String)
201 * @return a List of blog entry IDs
202 */
203 public List<String> getRecentBlogEntries(String username) {
/*
P/P * Method: List getRecentBlogEntries(String)
*
* Preconditions:
* this.authors != null
*
* Postconditions:
* return_value in Addr_Set{&new LinkedList(getRecentBlogEntries#2),&new LinkedList(getRecentBlogEntries#1)}
* new LinkedList(getRecentBlogEntries#1) num objects <= 1
* new LinkedList(getRecentBlogEntries#2) num objects <= 1
*
* Test Vectors:
* java.util.Map:get(...)@204: Inverse{null}, Addr_Set{null}
*/
204 List<String> blogEntries = authors.get(username);
205 if (blogEntries == null) {
206 return new LinkedList<String>();
207 } else {
208 return new LinkedList<String>(blogEntries);
209 }
210 }
211
212 }
SofCheck Inspector Build Version : 2.22510
| authorindex.java |
2010-Jun-25 19:40:32 |
| authorindex.class |
2010-Jul-19 20:23:38 |