1 // The Antville Project 2 // http://code.google.com/p/antville 3 // 4 // Copyright 2007-2011 by Tobi Schäfer. 5 // 6 // Copyright 2001–2007 Robert Gaggl, Hannes Wallnöfer, Tobi Schäfer, 7 // Matthias & Michael Platzer, Christoph Lincke. 8 // 9 // Licensed under the Apache License, Version 2.0 (the ``License''); 10 // you may not use this file except in compliance with the License. 11 // You may obtain a copy of the License at 12 // 13 // http://www.apache.org/licenses/LICENSE-2.0 14 // 15 // Unless required by applicable law or agreed to in writing, software 16 // distributed under the License is distributed on an ``AS IS'' BASIS, 17 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 // See the License for the specific language governing permissions and 19 // limitations under the License. 20 // 21 // $Revision$ 22 // $Author$ 23 // $Date$ 24 // $URL$ 25 26 /** 27 * @fileOverview Defines the Archive prototype. 28 */ 29 30 Archive.PAGER = "page"; 31 Archive.COLLECTION = "collection"; 32 33 /** 34 * @name Archive 35 * @constructor 36 * @param {Object} name 37 * @param {Object} type 38 * @param {Object} parent 39 * @property {Story[]} _children 40 * @property {String} name 41 * @property {String} parent 42 * @property {String} type 43 * @extends HopObject 44 */ 45 Archive.prototype.constructor = function(name, type, parent) { 46 this.name = name; 47 this.type = type; 48 this.parent = parent; 49 return this; 50 } 51 52 /** 53 * 54 * @param {String} name 55 * @returns {HopObject} 56 */ 57 Archive.prototype.getChildElement = function(name) { 58 if (name.startsWith(Archive.PAGER)) { 59 return new Archive(name, Archive.PAGER, this); 60 } else if (!isNaN(name)) { 61 return new Archive(name, Archive.COLLECTION, this); 62 } 63 return this.get(name); 64 } 65 66 /** 67 * 68 * @param {String} action 69 * @returns {Boolean} 70 */ 71 Archive.prototype.getPermission = function(action) { 72 var site = res.handlers.site; 73 if (!site.getPermission("main") || site.archiveMode !== Site.PUBLIC) { 74 return false; 75 } 76 switch (action) { 77 case "main": 78 case "page1": 79 return true; 80 case "previous": 81 return this.getPage() > 1 82 case "next": 83 return this.getPage() < this.getSize() / this.getPageSize(); 84 } 85 return false; 86 } 87 88 Archive.prototype.main_action = function() { 89 var date = this.getDate(); 90 var dateString = String.EMPTY; 91 switch (path.length - (this.type === Archive.PAGER ? 4 : 3)) { 92 case 1: 93 dateString = formatDate(date, "yyyy"); 94 break; 95 case 2: 96 dateString = formatDate(date, "MMM yyyy"); 97 break; 98 case 3: 99 var type = java.text.DateFormat.LONG; 100 var locale = res.handlers.site.getLocale(); 101 var pattern = java.text.DateFormat.getDateInstance(type, locale).toPattern() 102 dateString = formatDate(date, pattern); 103 break; 104 } 105 var page = gettext("Page {0} of {1}", this.getPage(), 106 Math.ceil(this.getSize() / this.getPageSize())); 107 res.data.title = gettext("Story Archive {0} ({1})", dateString, page); 108 res.data.body = this.renderSkinAsString("Archive#main"); 109 res.handlers.site.renderSkin("Site#page"); 110 res.handlers.site.log(); 111 return; 112 } 113 114 Archive.prototype.page1_action = function() { 115 return res.redirect(this.href()); 116 } 117 118 /** 119 * 120 * @param {String} action 121 * @returns {String} 122 */ 123 Archive.prototype.href = function(action) { 124 var buffer = []; 125 var archive = this; 126 while (archive.parent) { 127 buffer.push(archive.name); 128 archive = archive.parent; 129 } 130 buffer.push(res.handlers.site.href("archive")); 131 buffer.reverse(); 132 if (action) { 133 if (this.type === Archive.PAGER) { 134 buffer.pop(); 135 } 136 buffer.push(action); 137 } 138 return buffer.join("/"); 139 } 140 141 /** 142 * 143 * @param {Object} param 144 * @param {String} action 145 * @param {String} text 146 * @see renderLink 147 */ 148 Archive.prototype.link_macro = function(param, action, text) { 149 if (!this.getPermission(action)) { 150 return; 151 } 152 switch (action) { 153 case "previous": 154 var page = this.getPage() - 1; break; 155 case "next": 156 var page = this.getPage() + 1; break; 157 } 158 var action = "page" + page; 159 return renderLink.call(global, param, action, text, this); 160 } 161 162 /** 163 * 164 */ 165 Archive.prototype.stories_macro = function() { 166 var day, storyDay; 167 var page = this.getPage(); 168 var pageSize = this.getPageSize(); 169 170 var renderStory = function(story) { 171 storyDay = story.created.getDate(); 172 if (day !== storyDay) { 173 story.renderSkin("Story#date"); 174 day = storyDay; 175 } 176 story.renderSkin("Story#preview"); 177 return; 178 } 179 180 // FIXME: This is a little bit inconsistent and thus needs special care 181 var archive = this.type === Archive.PAGER ? this.parent : this; 182 if (!archive.parent) { 183 var site = res.handlers.site; 184 var offset = (page - 1) * pageSize; 185 var stories = site.stories.featured.list(offset, pageSize); 186 for each (var story in stories) { 187 renderStory(story); 188 }; 189 return; 190 } 191 192 var sql = new Sql; 193 sql.retrieve(Sql.ARCHIVE, res.handlers.site._id, this.getFilter(), 194 Sql.ARCHIVEORDER, pageSize, (page - 1) * pageSize); 195 sql.traverse(function() { 196 var story = Story.getById(this.id); 197 renderStory(story); 198 }); 199 return; 200 } 201 202 /** 203 * @returns {Number} 204 */ 205 Archive.prototype.getSize = function() { 206 // FIXME: This is a little bit inconsistent and thus needs special care 207 var archive = this.type === Archive.PAGER ? this.parent : this; 208 if (!archive.parent) { 209 return res.handlers.site.stories.featured.size(); 210 } 211 var size; 212 var sql = new Sql; 213 sql.retrieve(Sql.ARCHIVESIZE, res.handlers.site._id, this.getFilter()); 214 sql.traverse(function() { 215 size = this.count; 216 return; 217 }); 218 return size; 219 } 220 221 /** 222 * @param {boolean} 223 * @returns {String} 224 */ 225 Archive.prototype.getFilter = function() { 226 var buffer = []; 227 var archive = this; 228 do { 229 if (archive.type === Archive.COLLECTION) { 230 buffer.unshift(Number(archive.name)); 231 } 232 } while (archive = archive.parent); 233 234 if (buffer.length < 0) { 235 var now = new Date; 236 buffer.push(now.getDate()); 237 buffer.push(now.getMonth() + 1); 238 buffer.push(now.getFullYear()); 239 } 240 241 res.push(); 242 var sql = new Sql; 243 var keys = ["year", "month", "day"]; 244 for (var i in buffer) { 245 sql.retrieve(Sql.ARCHIVEPART, keys[i], buffer[i]); 246 res.write(sql); 247 } 248 return res.pop(); 249 } 250 251 /** 252 * @returns {Number} 253 */ 254 Archive.prototype.getPage = function() { 255 if (this.type === Archive.PAGER) { 256 return Number(this.name.substr(4)); 257 } 258 return 1; 259 } 260 261 /** 262 * @returns {Number} 263 */ 264 Archive.prototype.getPageSize = function() { 265 return res.handlers.site.pageSize; 266 } 267 268 /** 269 * @returns {Date} 270 */ 271 Archive.prototype.getDate = function() { 272 var date = new Date; 273 var offset = path.contains(res.handlers.site.archive) + 1; 274 if (offset > -1) { 275 var archive; 276 var buffer = []; 277 for (var i=offset; i<path.length; i+=1) { 278 archive = path[i]; 279 if (archive.type === Archive.COLLECTION) { 280 buffer.push(Number(archive.name)); 281 } 282 } 283 } 284 buffer[0] && date.setYear(buffer[0]); 285 buffer[1] && date.setMonth(buffer[1] - 1); 286 buffer[2] && date.setDate(buffer[2]); 287 return date; 288 } 289