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