001package votorola.s.wap; // Copyright 2012, Michael Allan. 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 java.io.*; 004import javax.servlet.http.*; 005import votorola.a.count.*; 006import votorola.a.web.wap.*; 007import votorola.g.io.*; 008import votorola.g.lang.*; 009import votorola.g.web.*; 010 011 012/** A web API for listing compiled <a href='http://reluk.ca/w/Category:Poll' target='_top'>polls</a>, 013 * which are defined as those with counts reported through 014 * <code>vocount</code>. Calls to this interface are conventionally prefixed by 'ps' 015 * (<code>wCall=psPollspace</code>). If you choose a different prefix, then adjust the 016 * parameter names below accordingly. An example request is: 017 * 018 * <blockquote><code><a href='http://reluk.ca:8080/v/wap?wCall=psPollspace&wPretty' target='_top'>http://reluk.ca:8080/v/wap?wCall=psPollspace&wPretty</a></code></blockquote> 019 * 020 * <p>The response includes the following components. These are shown in JSON format 021 * with explanatory comments:</p><pre 022 * 023 *> { 024 * "ps": [ // or other prefix, per {@linkplain WAP wCall} query parameter 025 * // Compiled polls in {@linkplain votorola.a.count.PollService#compareTo(PollService) natural order}: 026 * { 027 * "{@linkplain Poll#name() name}": "POLL NAME 1", 028 * "{@linkplain Poll#displayTitle() displayTitle}": "DISPLAY TITLE", // if any 029 * "{@linkplain Poll#issueType() issueType}": "ISSUE TYPE" 030 * }, 031 * { 032 * "{@linkplain Poll#name() name}": "POLL NAME 2", 033 * "{@linkplain Poll#issueType() issueType}": "ISSUE TYPE" 034 * } 035 * // and so on, up to {@value MAX_RESPONSE_SIZE} 036 * ] 037 * }</pre> 038 * 039 * @see <a href='../../../../../s/manual.xht#line-vocount'>vocount</a> 040 */ 041public @ThreadRestricted("constructor") final class PollspaceWAP extends Call 042{ 043 044 045 /** Constructs a PollspaceWAP. 046 * 047 * @see #prefix() 048 * @see #req() 049 */ 050 public PollspaceWAP( final String prefix, final Requesting req, 051 final ResponseConfiguration resConfig ) throws HTTPRequestException 052 { 053 super( prefix, req, resConfig ); 054 final File readyToReportLink = 055 req.wap().vsRun().voteServer().scopeCount().readyToReportLink(); 056 if( readyToReportLink.exists() ) 057 { 058 try 059 { 060 final ReadyDirectory dir = new ReadyDirectory( 061 readyToReportLink.getCanonicalPath() ); 062 pollspace0CacheOrNull = req.wPretty()? dir.pollspace0PCache(): dir.pollspace0Cache(); 063 } 064 catch( IOException x ) { throw new RuntimeException( x ); } 065 } 066 else pollspace0CacheOrNull = null; 067 } 068 069 070 071 // ------------------------------------------------------------------------------------ 072 073 074 /** The name to use in the {@link WAP wCall} query parameter, which is {@value}. For 075 * example: <code>wCall=psPollspace</code>. 076 */ 077 public static final String CALL_TYPE = "Pollspace"; 078 079 080 081 /** The maximum number of polls returned per response. No paging mechanism is 082 * provided yet, so polls beyond this number are currently inaccessible. 083 */ 084 public static final int MAX_RESPONSE_SIZE = 500; 085 086 087 088 // - C a l l -------------------------------------------------------------------------- 089 090 091 public void respond( final Responding res ) throws java.io.IOException 092 { 093 res.outJSON().flush(); 094 final Writer outBuf = res.outBuf(); 095 final boolean wPretty = res.wPretty(); 096 if( wPretty ) outBuf.append( '\n' ).append( res.outJSONIndent() ); 097 outBuf.append( '"' ).append( prefix() ).append( "\":" ); if( wPretty ) outBuf.append( ' ' ); 098 if( pollspace0CacheOrNull == null ) outBuf.append( "[]" ); 099 else 100 { 101 FileX.appendTo( outBuf, pollspace0CacheOrNull, java.nio.charset.StandardCharsets.UTF_8 ); 102 } 103 // if( wPretty ) outBuf.append( '\n' ); 104 /// but prettier without that, as indentation slightly off in pollspace0CacheOrNull 105 } 106 107 108 109//// P r i v a t e /////////////////////////////////////////////////////////////////////// 110 111 112 private final File pollspace0CacheOrNull; 113 114 115}