001/*
002 * Copyright (c) 2012, the Last.fm Java Project and Committers
003 * All rights reserved.
004 *
005 * Redistribution and use of this software in source and binary forms, with or without modification, are
006 * permitted provided that the following conditions are met:
007 *
008 * - Redistributions of source code must retain the above
009 *   copyright notice, this list of conditions and the
010 *   following disclaimer.
011 *
012 * - Redistributions in binary form must reproduce the above
013 *   copyright notice, this list of conditions and the
014 *   following disclaimer in the documentation and/or other
015 *   materials provided with the distribution.
016 *
017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
018 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
019 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
020 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
021 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
023 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
024 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
025 */
026
027package de.umass.lastfm;
028
029import java.util.ArrayList;
030import java.util.Collection;
031import java.util.Collections;
032
033import de.umass.xml.DomElement;
034
035/**
036 * This utility class can be used to generically generate Result objects (usually Lists or {@link PaginatedResult}s) from an XML response
037 * using {@link ItemFactory ItemFactories}.
038 *
039 * @author Janni Kovacs
040 */
041public final class ResponseBuilder {
042
043        private ResponseBuilder() {
044        }
045
046        private static <T> ItemFactory<T> getItemFactory(Class<T> itemClass) {
047                return ItemFactoryBuilder.getFactoryBuilder().getItemFactory(itemClass);
048        }
049
050        public static <T> Collection<T> buildCollection(Result result, Class<T> itemClass) {
051                return buildCollection(result, getItemFactory(itemClass));
052        }
053
054        public static <T> Collection<T> buildCollection(Result result, ItemFactory<T> factory) {
055                if (!result.isSuccessful())
056                        return Collections.emptyList();
057                return buildCollection(result.getContentElement(), factory);
058        }
059
060        public static <T> Collection<T> buildCollection(DomElement element, Class<T> itemClass) {
061                return buildCollection(element, getItemFactory(itemClass));
062        }
063
064        public static <T> Collection<T> buildCollection(DomElement element, ItemFactory<T> factory) {
065                if (element == null)
066                        return Collections.emptyList();
067                Collection<DomElement> children = element.getChildren();
068                Collection<T> items = new ArrayList<T>(children.size());
069                for (DomElement child : children) {
070                        items.add(factory.createItemFromElement(child));
071                }
072                return items;
073        }
074
075        public static <T> PaginatedResult<T> buildPaginatedResult(Result result, Class<T> itemClass) {
076                return buildPaginatedResult(result, getItemFactory(itemClass));
077        }
078
079        public static <T> PaginatedResult<T> buildPaginatedResult(Result result, ItemFactory<T> factory) {
080                if (!result.isSuccessful()) {
081                        return new PaginatedResult<T>(0, 0, Collections.<T>emptyList());
082                }
083
084                DomElement contentElement = result.getContentElement();
085                return buildPaginatedResult(contentElement, contentElement, factory);
086        }
087
088        public static <T> PaginatedResult<T> buildPaginatedResult(DomElement contentElement, DomElement childElement, Class<T> itemClass) {
089                return buildPaginatedResult(contentElement, childElement, getItemFactory(itemClass));
090        }
091
092        public static <T> PaginatedResult<T> buildPaginatedResult(DomElement contentElement, DomElement childElement, ItemFactory<T> factory) {
093                Collection<T> items = buildCollection(childElement, factory);
094
095                String totalPagesAttribute = contentElement.getAttribute("totalPages");
096                if (totalPagesAttribute == null)
097                        totalPagesAttribute = contentElement.getAttribute("totalpages");
098
099                int page = Integer.parseInt(contentElement.getAttribute("page"));
100                int totalPages = Integer.parseInt(totalPagesAttribute);
101
102                return new PaginatedResult<T>(page, totalPages, items);
103        }
104
105        public static <T> T buildItem(Result result, Class<T> itemClass) {
106                return buildItem(result, getItemFactory(itemClass));
107        }
108
109        public static <T> T buildItem(Result result, ItemFactory<T> factory) {
110                if (!result.isSuccessful())
111                        return null;
112                return buildItem(result.getContentElement(), factory);
113        }
114
115        public static <T> T buildItem(DomElement element, Class<T> itemClass) {
116                return buildItem(element, getItemFactory(itemClass));
117        }
118
119        private static <T> T buildItem(DomElement element, ItemFactory<T> factory) {
120                return factory.createItemFromElement(element);
121        }
122}