Package org.socialmusicdiscovery.server.business.service.browse

Source Code of org.socialmusicdiscovery.server.business.service.browse.LibraryBrowseService

/*
*  Copyright 2010-2011, Social Music Discovery project
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions are met:
*      * Redistributions of source code must retain the above copyright
*        notice, this list of conditions and the following disclaimer.
*      * Redistributions in binary form must reproduce the above copyright
*        notice, this list of conditions and the following disclaimer in the
*        documentation and/or other materials provided with the distribution.
*      * Neither the name of Social Music Discovery project nor the
*        names of its contributors may be used to endorse or promote products
*        derived from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED. IN NO EVENT SHALL SOCIAL MUSIC DISCOVERY PROJECT BE LIABLE FOR ANY
*  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
*  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.socialmusicdiscovery.server.business.service.browse;

import com.google.inject.Inject;
import org.socialmusicdiscovery.server.business.logic.InjectHelper;
import org.socialmusicdiscovery.server.business.logic.config.ConfigurationManager;
import org.socialmusicdiscovery.server.business.logic.config.MergedConfigurationManager;
import org.socialmusicdiscovery.server.business.logic.config.PersistentConfigurationManager;
import org.socialmusicdiscovery.server.business.model.SMDIdentity;
import org.socialmusicdiscovery.server.support.format.TitleFormat;

import java.util.*;

public class LibraryBrowseService {
    @Inject
    BrowseServiceManager browseServiceManager;

    @Inject
    BrowseMenuManager browseMenuManager;

    @Inject
    ObjectTypeBrowseService objectTypeBrowseService;

    private ConfigurationManager configurationManager;

    public LibraryBrowseService() {
        InjectHelper.injectMembers(this);
        configurationManager = new MergedConfigurationManager(new PersistentConfigurationManager());
    }

    protected Collection<MenuLevel> getMenus(String context) {
        return browseMenuManager.getAllMenus(BrowseMenuManager.MenuType.LIBRARY, context);
    }

    public Result<Object> findChildren(String clientType, String parentPath, Integer firstItem, Integer maxItems, Boolean counts) {
        return findChildren(clientType, null, parentPath, firstItem, maxItems, counts);
    }

    protected Result<Object> findChildren(String clientType, String currentId, String parentPath, Integer firstItem, Integer maxItems, Boolean counts) {
        Result<Object> result = new Result<Object>();
        if (counts == null) {
            counts = false;
        }

        String currentType = null;
        if (currentId != null && currentId.contains(":")) {
            currentType = currentId.substring(0, currentId.indexOf(":"));
        }
        String currentBaseType = currentType;
        if (currentBaseType != null && currentBaseType.contains(".")) {
            currentBaseType = currentBaseType.substring(0, currentBaseType.indexOf("."));
        }

        String currentPath = parentPath;

        // Get all menus for current context type
        Collection<MenuLevel> menus = getMenus(currentType);
        Collection<MenuLevel> possibleLevels = menus;

        if (currentPath == null) {
            currentPath = "";
        }

        // Build criteria map
        Map<String, String> criteriaMap = new HashMap<String, String>();
        StringTokenizer tokens = new StringTokenizer(currentPath, "/");
        while (tokens.hasMoreElements()) {
            String token = tokens.nextToken();
            if (token.startsWith(MenuLevelFolder.TYPE+":")) {
                // We need to make folder items unique
                criteriaMap.put(token,null);
            }else if (token.startsWith(MenuLevelImageFolder.TYPE + ":")) {
                // We need to make folder items unique
                criteriaMap.put(token,null);
            }else if(token.startsWith(MenuLevelCommand.TYPE+":")) {
                // We need to make command items unique
                criteriaMap.put(token,null);
            }else if (token.contains(":")) {
                criteriaMap.put(token.substring(0, token.indexOf(":")), token.substring(token.indexOf(":") + 1));
            } else {
                criteriaMap.put(token, null);
            }
        }

        // Add context to criteria
        List<String> criterias = new ArrayList<String>();
        int criteriaOffset = 0;
        if (currentId != null) {
            criterias.add(currentId);
            criteriaOffset = 1;
        }

        Map<String, String> remainingCriteria = new HashMap<String, String>(criteriaMap);
        // Find the next menu level which we should return data for
        boolean found = true;
        while (found && possibleLevels != null) {
            found = false;
            for (MenuLevel level : possibleLevels) {
                if (remainingCriteria.containsKey(level.getId())) {
                    String value = remainingCriteria.get(level.getId());
                    if (value != null) {
                        criterias.add(level.getType() + ":" + value);
                    }
                    remainingCriteria.remove(level.getId());
                    possibleLevels = level.getChildLevels();
                    found = true;
                    break;
                }
            }
        }

        // Add context to criteria map
        if(currentId!=null && currentId.contains(":")) {
            criteriaMap.put(currentId.substring(0,currentId.indexOf(":")), currentId.substring(currentId.indexOf(":")+1));
        }

        // If a matching level was found which have childs
        if (possibleLevels != null) {
            for (MenuLevel requestedObjectType : possibleLevels) {
                if(!requestedObjectType.isVisibleForClientType(clientType)) {
                    continue;
                }
                if (maxItems != null && maxItems < 0) {
                    maxItems=0;
                }

                Result browseResult = new Result<Object>();

                // Static menus are just added as a single item
                if (!(requestedObjectType instanceof MenuLevelDynamic)) {
                    if ((firstItem == null || firstItem == 0) && (maxItems==null||maxItems>0)) {
                        ResultItem<Object> item = new ResultItem<Object>(null, requestedObjectType.getType(), requestedObjectType.getId(), requestedObjectType.getDisplayName(), requestedObjectType.isPlayable(), requestedObjectType.getChildLevels() == null);
                        if(requestedObjectType instanceof MenuLevelCommand && ((MenuLevelCommand)requestedObjectType).getParameters()!=null) {
                            List<String> parameters = new ArrayList<String>();
                            for (String name : ((MenuLevelCommand)requestedObjectType).getParameters()) {
                                String value = criteriaMap.get(name);
                                if(value!=null) {
                                    parameters.add(name+":"+value);
                                }
                            }
                            item.setParameters(parameters);
                        }
                        browseResult = new Result<Object>(1, new ArrayList<ResultItem<Object>>(Arrays.asList(item)));
                        if(counts) {
                            Map<String, Long> childCounters = new HashMap<String, Long>();
                            for (MenuLevel childLevel : requestedObjectType.getChildLevels()) {
                                if(!(childLevel instanceof MenuLevelDynamic)) {
                                    childCounters.put(childLevel.getId(), 1L);
                                }else {
                                    List<String> criteriasForThisLevel = new ArrayList<String>(criterias);

                                    String requestedMainObjectType = null;
                                    if (childLevel.getType().contains(".")) {
                                        requestedMainObjectType = childLevel.getType().substring(0, childLevel.getType().indexOf("."));
                                        criteriasForThisLevel.add(childLevel.getType());
                                    } else {
                                        requestedMainObjectType = childLevel.getType();
                                    }

                                    // Remove criterias according to criteria depth for selected menu item
                                    if (childLevel instanceof MenuLevelDynamic && ((MenuLevelDynamic)childLevel).getCriteriaDepth() != null) {
                                        while (criteriasForThisLevel.size() > ((MenuLevelDynamic)childLevel).getCriteriaDepth()) {
                                            criteriasForThisLevel.remove(0);
                                        }
                                    }

                                    // Lookup and call browse service
                                    BrowseService browseService = browseServiceManager.getBrowseService(requestedMainObjectType);
                                    Integer count = browseService.findChildrenCount(criteriasForThisLevel);
                                    childCounters.put(childLevel.getId(), count.longValue());
                                }
                            }
                            item.setChildItems(childCounters);
                        }
                    } else {
                        browseResult = new Result<Object>();
                        browseResult.setCount(1);
                    }

                // Dynamic menus retrieves their data using browse services
                } else {
                    List<String> criteriasForThisLevel = new ArrayList<String>(criterias);

                    // Detect type of object we want to retrieve
                    String requestedMainObjectType = null;
                    if (requestedObjectType.getType().contains(".")) {
                        requestedMainObjectType = requestedObjectType.getType().substring(0, requestedObjectType.getType().indexOf("."));
                        criteriasForThisLevel.add(requestedObjectType.getType());
                    } else {
                        requestedMainObjectType = requestedObjectType.getType();
                    }

                    // Remove criterias according to criteria depth for selected menu item
                    if (((MenuLevelDynamic)requestedObjectType).getCriteriaDepth() != null) {
                        while (criteriasForThisLevel.size() > ((MenuLevelDynamic)requestedObjectType).getCriteriaDepth()) {
                            criteriasForThisLevel.remove(0);
                        }
                    }

                    TitleFormat parser = null;
                    if(((MenuLevelDynamic)requestedObjectType).getFormat()!=null) {
                        parser = new TitleFormat(((MenuLevelDynamic)requestedObjectType).getFormat());
                    }

                    // Lookup and call browse service
                    BrowseService browseService = browseServiceManager.getBrowseService(requestedMainObjectType);
                    browseResult = browseService.findChildren(criteriasForThisLevel, new ArrayList<String>(), firstItem, maxItems, counts);

                    if (maxItems == null || maxItems >0) {
                        // Iterate through browse service result and create appropriate items
                        Collection<ResultItem> browseResultItems = browseResult.getItems();
                        for (ResultItem item : browseResultItems) {
                            String id;
                            if (item.getItem() instanceof SMDIdentity) {
                                id = requestedObjectType.getType() + ":" + ((SMDIdentity) item.getItem()).getId();
                            } else {
                                id = requestedObjectType.getType() + ":" + item.getItem().toString();
                            }
                            item.setId(id);
                            item.setType(requestedMainObjectType);
                            if(parser != null) {
                                item.setName(requestedObjectType.getDisplayName()+parser.format(item.getItem()));
                            }else {
                                item.setName(requestedObjectType.getDisplayName()+item.getItem().toString());
                            }
                            item.setPlayable(requestedObjectType.isPlayable());
                            item.setLeaf(requestedObjectType.getChildLevels() == null);

                            if (counts) {
                                Map<String, Long> childCounters = new HashMap<String, Long>();
                                if(requestedObjectType.getChildLevels()!=null) {
                                    for (MenuLevel childLevel : requestedObjectType.getChildLevels()) {
                                        if (item.getChildItems()!=null && item.getChildItems().containsKey(childLevel.getType())) {
                                            childCounters.put(childLevel.getType(), (Long) item.getChildItems().get(childLevel.getType()));
                                        }
                                    }
                                }
                                item.setChildItems(childCounters);
                            }
                        }
                    }else {
                        Integer count = browseResult.getCount();
                        browseResult = new Result<Object>();
                        browseResult.setCount(count);
                    }
                }

                // Decrease max items in case there are more menu levels to retrieve data for
                if (maxItems != null && browseResult.getItems().size()>0) {
                    maxItems = maxItems - browseResult.getItems().size();
                    if (maxItems < 0) {
                        maxItems = 0;
                    }
                }

                // Set offset to 0 in case there are more menu levels to retrieve data for
                if (firstItem != null && browseResult.getItems().size() > 0) {
                    firstItem = 0;
                }else if(firstItem != null) {
                    firstItem = firstItem - browseResult.getCount();
                    if(firstItem<0) {
                        firstItem = 0;
                    }
                }
                result.setCount(result.getCount() + browseResult.getCount());
                if (result.getAlphabetic() != null && browseResult.getAlphabetic() != null) {
                    result.setAlphabetic(result.getAlphabetic() && browseResult.getAlphabetic());
                } else {
                    result.setAlphabetic(null);
                }
                result.getItems().addAll(browseResult.getItems());
            }
        }

        fillContext(result, currentBaseType, currentId);
        return result;
    }

    private void fillContext(Result result, String currentBaseType, String currentId) {
        if (currentId != null && currentId.contains(":") && currentBaseType != null) {
            if(!currentBaseType.equals(MenuLevelFolder.TYPE) &&
                    !currentBaseType.equals(MenuLevelImageFolder.TYPE) &&
                    !currentBaseType.equals(MenuLevelCommand.TYPE)) {

                BrowseService browseService = browseServiceManager.getBrowseService(currentBaseType);
                if (browseService != null) {
                    ResultItem currentItem = browseService.findById(currentId.substring(currentId.indexOf(":") + 1));
                    if (currentItem != null) {
                        if (currentItem.getName() == null) {
                            String format = browseMenuManager.getDefaultItemFormat(BrowseMenuManager.MenuType.CONTEXT, currentItem.getType());
                            if (format != null) {
                                currentItem.setName(new TitleFormat(format).format(currentItem.getItem()));
                            }
                        }
                        result.setContext(currentItem);
                    }
                }
            }
        }
    }
}
TOP

Related Classes of org.socialmusicdiscovery.server.business.service.browse.LibraryBrowseService

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.