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}