001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019package org.apache.isis.viewer.restfulobjects.applib.client;
020
021import java.net.URI;
022
023import javax.ws.rs.core.MediaType;
024import javax.ws.rs.core.Response;
025
026import org.apache.http.client.HttpClient;
027import org.apache.http.conn.ClientConnectionManager;
028import org.apache.http.impl.client.DefaultHttpClient;
029import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
030import org.jboss.resteasy.client.ClientExecutor;
031import org.jboss.resteasy.client.ClientRequestFactory;
032import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
033
034import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
035import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
036import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
037import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainObjectResource;
038import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
039import org.apache.isis.viewer.restfulobjects.applib.domaintypes.DomainTypeResource;
040import org.apache.isis.viewer.restfulobjects.applib.homepage.HomePageResource;
041import org.apache.isis.viewer.restfulobjects.applib.user.UserResource;
042import org.apache.isis.viewer.restfulobjects.applib.version.VersionResource;
043
044public class RestfulClient {
045
046    private final HomePageResource homePageResource;
047    private final UserResource userResource;
048    private final VersionResource versionResource;
049    private final DomainObjectResource domainObjectResource;
050    private final DomainServiceResource domainServiceResource;
051    private final DomainTypeResource domainTypeResource;
052
053    private final ClientExecutor executor;
054    private final ClientRequestFactory clientRequestFactory;
055
056    
057    /**
058     * Using {@link ApacheHttpClient4Executor} and {@link DefaultHttpClient}.
059     */
060    public RestfulClient(final URI baseUri) {
061        this(baseUri, new ThreadSafeClientConnManager());
062    }
063
064    /**
065     * Using {@link ApacheHttpClient4Executor} and {@link DefaultHttpClient}.
066     */
067    public RestfulClient(final URI baseUri, ClientConnectionManager clientConnectionManager) {
068        this(baseUri, new DefaultHttpClient(clientConnectionManager));
069    }
070
071
072    /**
073     * Using {@link ApacheHttpClient4Executor} and specified {@link HttpClient}.
074     */
075    public RestfulClient(final URI baseUri, HttpClient client) {
076        this(baseUri, new ApacheHttpClient4Executor(client));
077    }
078
079    /**
080     * Using arbitrary {@link ClientExecutor} implementation.
081     */
082    public RestfulClient(final URI baseUri, final ClientExecutor clientExecutor) {
083        this.executor = clientExecutor;
084        this.clientRequestFactory = new ClientRequestFactory(clientExecutor, baseUri);
085
086        this.homePageResource = clientRequestFactory.createProxy(HomePageResource.class);
087        this.userResource = clientRequestFactory.createProxy(UserResource.class);
088        this.domainTypeResource = clientRequestFactory.createProxy(DomainTypeResource.class);
089        this.domainServiceResource = clientRequestFactory.createProxy(DomainServiceResource.class);
090        this.domainObjectResource = clientRequestFactory.createProxy(DomainObjectResource.class);
091        this.versionResource = clientRequestFactory.createProxy(VersionResource.class);
092    }
093
094    // ///////////////////////////////////////////////////////////////
095    // resources
096    // ///////////////////////////////////////////////////////////////
097
098    public HomePageResource getHomePageResource() {
099        return homePageResource;
100    }
101
102    public UserResource getUserResource() {
103        return userResource;
104    }
105
106    public VersionResource getVersionResource() {
107        return versionResource;
108    }
109
110    public DomainTypeResource getDomainTypeResource() {
111        return domainTypeResource;
112    }
113
114    public DomainObjectResource getDomainObjectResource() {
115        return domainObjectResource;
116    }
117
118    public DomainServiceResource getDomainServiceResource() {
119        return domainServiceResource;
120    }
121
122    // ///////////////////////////////////////////////////////////////
123    // resource walking support
124    // ///////////////////////////////////////////////////////////////
125
126    public RepresentationWalker createWalker(final Response response) {
127        return new RepresentationWalker(this, response);
128    }
129
130    public RestfulResponse<JsonRepresentation> follow(final LinkRepresentation link) throws Exception {
131        return followT(link);
132    }
133
134    public <T extends JsonRepresentation> RestfulResponse<T> followT(final LinkRepresentation link) throws Exception {
135        return followT(link, JsonRepresentation.newMap());
136    }
137
138    public RestfulResponse<JsonRepresentation> follow(final LinkRepresentation link, final JsonRepresentation requestArgs) throws Exception {
139        return followT(link, requestArgs);
140    }
141
142    public <T extends JsonRepresentation> RestfulResponse<T> followT(final LinkRepresentation link, final JsonRepresentation requestArgs) throws Exception {
143        return link.<T> follow(executor, requestArgs);
144    }
145
146    public RestfulRequest createRequest(final RestfulHttpMethod httpMethod, final String uriTemplate) {
147
148        final boolean includesScheme = uriTemplate.startsWith("http:") || uriTemplate.startsWith("https:");
149        final String base = clientRequestFactory.getBase().toString();
150        final String uri = (includesScheme ? "" : base) + uriTemplate;
151
152        final ClientRequestConfigurer clientRequestConfigurer = ClientRequestConfigurer.create(executor, uri);
153
154        clientRequestConfigurer.accept(MediaType.APPLICATION_JSON_TYPE);
155        clientRequestConfigurer.setHttpMethod(httpMethod);
156
157        return new RestfulRequest(clientRequestConfigurer);
158    }
159
160    /**
161     * exposed for testing purposes only.
162     */
163    public ClientRequestFactory getClientRequestFactory() {
164        return clientRequestFactory;
165    }
166
167}