001/* 002 * JKNIV, whinstone one contract to access your database. 003 * 004 * Copyright (C) 2017, the original author or authors. 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software Foundation, Inc., 018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 019 */ 020package net.sf.jkniv.whinstone.couchdb.commands; 021 022import java.io.IOException; 023import java.sql.Statement; 024import java.util.ArrayList; 025import java.util.Collections; 026import java.util.List; 027 028import org.apache.http.client.methods.CloseableHttpResponse; 029import org.apache.http.client.methods.HttpGet; 030import org.apache.http.impl.client.CloseableHttpClient; 031import org.apache.http.impl.client.HttpClients; 032import org.apache.http.util.EntityUtils; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036import net.sf.jkniv.sqlegance.RepositoryException; 037import net.sf.jkniv.whinstone.Queryable; 038import net.sf.jkniv.whinstone.couchdb.CouchDbResult; 039import net.sf.jkniv.whinstone.couchdb.HttpBuilder; 040 041@SuppressWarnings({ "unchecked", "rawtypes" }) 042public class ViewCommand extends AbstractCommand implements CouchCommand 043{ 044 private static final Logger LOG = LoggerFactory.getLogger(ViewCommand.class); 045 private final Queryable queryable; 046 private final HttpBuilder httpBuilder; 047 public ViewCommand(HttpBuilder httpBuilder, Queryable queryable) 048 { 049 super(); 050 this.httpBuilder = httpBuilder; 051 this.queryable = queryable; 052 } 053 054 @Override 055 public <T> T execute() 056 { 057 String json = null; 058 CloseableHttpResponse response = null; 059 CouchDbResult answer = null; 060 List list = Collections.emptyList(); 061 try 062 { 063 CloseableHttpClient httpclient = HttpClients.createDefault(); 064 String url = httpBuilder.getUrlForView(queryable); 065 HttpGet http = (HttpGet) asGet().newHttp(url); 066 httpBuilder.setHeader(http); 067 printRequest(http); 068 response = httpclient.execute(http); 069 json = EntityUtils.toString(response.getEntity()); 070 printResponse(response, json); 071 072 int statusCode = response.getStatusLine().getStatusCode(); 073 if (isOk(statusCode)) 074 { 075 JsonMapper.setCurrentQuery(queryable); 076 answer = JsonMapper.MAPPER.readerFor(CouchDbResultImpl.class).readValue(json); 077 if(CouchDbResult.class.isAssignableFrom(queryable.getReturnType())) 078 { 079 list = new ArrayList(); 080 list.add(answer); 081 } 082 else 083 list = answer.getRows(); 084 if(queryable.isPaging()) 085 queryable.setTotal(Statement.SUCCESS_NO_INFO); 086 else 087 queryable.setTotal(answer.getTotalRows()); 088 } 089 else if (isNotFound(statusCode)) 090 { 091 // 204 No Content, 304 Not Modified, 205 Reset Content 092 queryable.setTotal(0); 093 LOG.warn(errorFormat(http, response.getStatusLine(), json)); 094 } 095 else 096 { 097 LOG.error(errorFormat(http, response.getStatusLine(), json)); 098 throw new RepositoryException(response.getStatusLine().toString()); 099 } 100 } 101 catch (Exception e) // ClientProtocolException | JsonParseException | JsonMappingException | IOException 102 { 103 queryable.setTotal(Statement.EXECUTE_FAILED); 104 handlerException.handle(e); 105 } 106 finally 107 { 108 if (response != null) 109 { 110 try 111 { 112 response.close(); 113 } 114 catch (IOException e) 115 { 116 handlerException.handle(e); 117 } 118 } 119 } 120 if (list == null) 121 list = Collections.emptyList(); 122 return (T) list; 123 } 124 125 @Override 126 public String getBody() 127 { 128 return this.body; 129 } 130 131 @Override 132 public HttpMethod asGet() 133 { 134 this.method = HttpMethod.GET; 135 return this.method; 136 } 137 138 @Override 139 public HttpMethod asHead() 140 { 141 this.method = HttpMethod.HEAD; 142 return this.method; 143 } 144 145 @Override 146 public HttpMethod asPost() 147 { 148 this.method = HttpMethod.POST; 149 return this.method; 150 } 151}