Package org.jclouds.abiquo.functions.pagination

Source Code of org.jclouds.abiquo.functions.pagination.ParseUsers$UserPaginatedCollection

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.jclouds.abiquo.functions.pagination;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.getFirst;
import static org.jclouds.http.utils.Queries.encodeQueryLine;
import static org.jclouds.http.utils.Queries.queryParser;

import java.net.URI;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.jclouds.abiquo.AbiquoApi;
import org.jclouds.abiquo.domain.PaginatedCollection;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseXMLWithJAXB;

import com.abiquo.model.rest.RESTLink;
import com.abiquo.server.core.enterprise.UserDto;
import com.abiquo.server.core.enterprise.UsersDto;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Multimap;

/**
* Parses a paginated user list.
*/
@Singleton
public class ParseUsers extends BasePaginationParser<UserDto, UsersDto> {
   @Inject
   public ParseUsers(AbiquoApi api, ParseXMLWithJAXB<UsersDto> parser) {
      super(api, parser);
   }

   // Return a custom class to bypass
   // http://jira.abiquo.com/browse/ABICLOUDPREMIUM-5927
   // Remove once the fix has been deployed to production
   @Override
   public PaginatedCollection<UserDto, UsersDto> apply(HttpResponse input) {
      return new UserPaginatedCollection(api, parser.apply(input), parser);
   }

   @Singleton
   public static class ToPagedIterable extends PaginatedCollection.ToPagedIterable<UserDto, UsersDto> {
      @Inject
      public ToPagedIterable(AbiquoApi api, ParseXMLWithJAXB<UsersDto> parser) {
         super(api, parser);
      }

      // Overwrite to return a custom class and bypass
      // http://jira.abiquo.com/browse/ABICLOUDPREMIUM-5927
      // Remove once the fix has been deployed to production
      @Override
      protected Function<Object, IterableWithMarker<UserDto>> nextPage(PaginatedCollection<UserDto, UsersDto> input) {
         return new Function<Object, IterableWithMarker<UserDto>>() {
            @Override
            public IterableWithMarker<UserDto> apply(Object marker) {
               checkArgument(marker instanceof RESTLink, "Marker must be a RESTLink");
               RESTLink next = RESTLink.class.cast(marker);

               // The Abiquo API does not provide the media types in the
               // pagination links, but it will be the same type than the
               // current page, so just set it.
               next.setType(UsersDto.BASE_MEDIA_TYPE);

               UsersDto nextPage = parser.apply(api.get(next));
               return new UserPaginatedCollection(api, nextPage, parser);
            }
         };
      }
   }

   /**
    * This class is used to bypass
    * http://jira.abiquo.com/browse/ABICLOUDPREMIUM-5927
    * <p>
    * The issue has already been fixed but still not been deployed in
    * production. Once that is done, this class should be removed.
    *
    */
   private static class UserPaginatedCollection extends PaginatedCollection<UserDto, UsersDto> {
      public UserPaginatedCollection(AbiquoApi api, UsersDto delegate, ParseXMLWithJAXB<UsersDto> parser) {
         super(api, delegate, parser);
      }

      @Override
      public Optional<Object> nextMarker() {
         Optional<Object> next = super.nextMarker();
         // Pagination links are not consistent and a "next" link can be
         // returned even if there are no more pages. Overwrite the
         // default behavior to handle this, and to adapt the query
         // parameters returned in the pagination links to what the api
         // expects in the GET requests
         if (next.isPresent()) {
            checkArgument(next.get() instanceof RESTLink, "Marker must be a RESTLink");
            RESTLink link = RESTLink.class.cast(next.get());

            // Get the conflicting query parameters and remove them from the
            // query parameter map
            Multimap<String, String> params = queryParser().apply(URI.create(link.getHref()).getRawQuery());
            String limit = getFirst(params.removeAll("limit"), null);
            String startwith = getFirst(params.removeAll("startwith"), null);

            // Next page links always have both query parameters. Otherwise
            // assume there is no next page
            if (limit != null && startwith != null) {
               int resultsPerPage = Integer.parseInt(limit);
               int totalResults = delegate.getTotalSize();
               int pageNumber = Integer.parseInt(startwith) - resultsPerPage;

               // Check if there is really a next page, and then return the
               // marker with the appropriate values
               if (totalResults / (double) resultsPerPage > pageNumber + 1) {
                  params.put("numResults", limit);
                  params.put("page", String.valueOf(pageNumber + 1));

                  // Build the new URI stripping the existing query
                  // parameters and using the new ones
                  String uri = link.getHref().substring(0, link.getHref().indexOf('?') + 1);
                  uri += encodeQueryLine(params);

                  return Optional.<Object> of(new RESTLink(link.getRel(), uri));
               }
            }
         }

         return Optional.absent();
      }

      @Override
      public PagedIterable<UserDto> toPagedIterable() {
         return new ParseUsers.ToPagedIterable(api, parser).apply(this);
      }
   }

}
TOP

Related Classes of org.jclouds.abiquo.functions.pagination.ParseUsers$UserPaginatedCollection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.