/*
 * Copyright 2014 Danilo Reinert
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.reinert.requestor;

import java.util.Collection;

import io.reinert.requestor.uri.UriBuilder;

public class ResourceService<R, I, C extends Collection> implements ResourceInvoker<R, I> {

    protected final Requestor requestor;
    protected final UriBuilder uriBuilder;
    protected final Class<R> resourceType;
    protected final Class<I> idType;
    protected final Class<C> collectionType;
    private boolean asMatrixParam = false;

    protected ResourceService(Requestor requestor, String resourceUri, Class<R> resourceType, Class<I> idType,
                              Class<C> collectionType) {
        this.requestor = requestor;
        this.resourceType = resourceType;
        this.idType = idType;
        this.collectionType = collectionType;
        this.uriBuilder = UriBuilder.fromUri(resourceUri);
    }

    @Override
    public Promise<Collection<R>> get(String... params) {
        final UriBuilder reqUriBuilder = uriBuilder.clone();

        appendParamsToUri(reqUriBuilder, params);

        return requestor.req(reqUriBuilder.build()).get(resourceType, collectionType);
    }

    @Override
    public Promise<R> get(I id, String... params) {
        final UriBuilder reqUriBuilder = uriBuilder.clone();

        reqUriBuilder.segment(id);

        appendParamsToUri(reqUriBuilder, params);

        return requestor.req(reqUriBuilder.build()).get(resourceType);
    }

    @Override
    public Promise<SerializedResponse> post(R resource) {
        final UriBuilder reqUriBuilder = uriBuilder.clone();

        return requestor.req(reqUriBuilder.build()).payload(resource).post(SerializedResponse.class);
    }

    @Override
    public Promise<SerializedResponse> put(I id, R resource) {
        final UriBuilder reqUriBuilder = uriBuilder.clone();

        reqUriBuilder.segment(id);

        return requestor.req(reqUriBuilder.build()).payload(resource).put(SerializedResponse.class);
    }

    @Override
    public Promise<SerializedResponse> delete(I id) {
        final UriBuilder reqUriBuilder = uriBuilder.clone();

        reqUriBuilder.segment(id);

        return requestor.req(reqUriBuilder.build()).delete(SerializedResponse.class);
    }

    @Override
    public RequestInvoker req() {
        final UriBuilder reqUriBuilder = uriBuilder.clone();

        return requestor.req(reqUriBuilder.build());
    }

    @Override
    public RequestInvoker req(I id) {
        final UriBuilder reqUriBuilder = uriBuilder.clone();

        reqUriBuilder.segment(id);

        return requestor.req(reqUriBuilder.build());
    }

    public void setAsMatrixParam(boolean asMatrixParam) {
        this.asMatrixParam = asMatrixParam;
    }

    public boolean isAsMatrixParam() {
        return this.asMatrixParam;
    }

    protected void appendParamsToUri(UriBuilder reqUriBuilder, String[] params) {
        // Check if params were given to the URI
        if (params != null && params.length > 0) {
            if (params.length % 2 > 0) {
                throw new IllegalArgumentException("It should have an even number of arguments, consisting of " +
                        "key and value pairs which will be appended to the request URI");
            }

            // Append the params to the request URI
            for (int i = 0; i < params.length; i = i + 2) {
                if (asMatrixParam) {
                    reqUriBuilder.matrixParam(params[i], params[i + 1]);
                } else {
                    reqUriBuilder.queryParam(params[i], params[i + 1]);
                }
            }
        }
    }
}

@@ -652,16 +652,53 @@
 ction;%0A%0A
+import io.reinert.requestor.uri.Uri;%0A
 import i
@@ -733,16 +733,16 @@
 uilder;%0A
-
 %0Apublic 
@@ -1078,16 +1078,46 @@
 = false;
+%0A    private String mediaType;
 %0A%0A    pr
@@ -1697,38 +1697,32 @@
   return request
-or.req
 (reqUriBuilder.b
@@ -2000,38 +2000,32 @@
   return request
-or.req
 (reqUriBuilder.b
@@ -2206,38 +2206,32 @@
   return request
-or.req
 (reqUriBuilder.b
@@ -2484,38 +2484,32 @@
   return request
-or.req
 (reqUriBuilder.b
@@ -2752,38 +2752,32 @@
   return request
-or.req
 (reqUriBuilder.b
@@ -2949,38 +2949,32 @@
   return request
-or.req
 (reqUriBuilder.b
@@ -3165,14 +3165,8 @@
 uest
-or.req
 (req
@@ -3379,24 +3379,427 @@
 ram;%0A    %7D%0A%0A
+    /**%0A     * Get default media type of this service.%0A     *%0A     * @return  media type%0A     */%0A    public String getMediaType() %7B%0A        return mediaType;%0A    %7D%0A%0A    /**%0A     * Set default media type to be added as Content-Type header in every request.%0A     *%0A     * @param mediaType HTTP media type%0A     */%0A    public void setMediaType(String mediaType) %7B%0A        this.mediaType = mediaType;%0A    %7D%0A%0A
     protecte
@@ -4571,32 +4571,32 @@
 %7D%0A            %7D%0A
-
         %7D%0A    %7D%0A
@@ -4594,11 +4594,192 @@
  %7D%0A    %7D
+%0A%0A    private RequestInvoker request(Uri uri) %7B%0A        if (mediaType != null)%0A            return requestor.req(uri).contentType(mediaType);%0A        return requestor.req(uri);%0A    %7D
 %0A%7D%0A

Add mediaType to ResourceService