001/*
002 *  Copyright 2012 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.tag;
017
018import java.util.HashSet;
019import java.util.Set;
020
021/**
022 * Helper class which provides useful methods to operate on {@link Tag} objects.
023 */
024public final class TagHelper
025{
026    private TagHelper()
027    {
028        // Hide the default constructor.
029    }
030    
031    /**
032     * Retrieves all descendants (direct and non-direct children) of the current tag.
033     * @param tag the current tag
034     * @param includeCurrent true to include the current tag itself
035     * @return the set of descendant tags.
036     */
037    public static Set<Tag> getDescendants(Tag tag, boolean includeCurrent)
038    {
039        return _getDescendants(tag, includeCurrent, null);
040    }
041    
042    private static Set<Tag> _getDescendants(Tag tag, boolean includeCurrent, Set<Tag> accumulator)
043    {
044        Set<Tag> tags = accumulator != null ? accumulator : new HashSet<>();
045        
046        if (tag != null)
047        {
048            if (includeCurrent)
049            {
050                tags.add(tag);
051            }
052            
053            for (Tag child : tag.getTags().values())
054            {
055                _getDescendants(child, true, tags);
056            }
057        }
058        
059        return tags;
060    }
061    
062    /**
063     * Retrieves all name of the descendants (direct and non-direct children) of the current tag.
064     * @param tag the current tag
065     * @param includeCurrent true to include the current tag itself
066     * @return the set of descendant tag names
067     */
068    public static Set<String> getDescendantNames(Tag tag, boolean includeCurrent)
069    {
070        Set<Tag> descendants = _getDescendants(tag, includeCurrent, null);
071        Set<String> descendantNames = new HashSet<>();
072        
073        // Tag to tag names
074        for (Tag descendant : descendants)
075        {
076            descendantNames.add(descendant.getName());
077        }
078        
079        return descendantNames;
080    }
081    
082    /**
083     * Retrieves all ancestors of the current tag.
084     * @param tag the current tag
085     * @param includeCurrent true to include the current tag itself
086     * @return the set of ancestor tags.
087     */
088    public static Set<Tag> getAncestors(Tag tag, boolean includeCurrent)
089    {
090        return _getAncestors(tag, includeCurrent, null);
091    }
092    
093    private static Set<Tag> _getAncestors(Tag tag, boolean includeCurrent, Set<Tag> accumulator)
094    {
095        Set<Tag> tags = accumulator != null ? accumulator : new HashSet<>();
096        
097        if (tag != null)
098        {
099            if (includeCurrent)
100            {
101                tags.add(tag);
102            }
103            
104            Tag parent = tag.getParent();
105            if (parent != null)
106            {
107                _getAncestors(parent, true, tags);
108            }
109        }
110        
111        return tags;
112    }
113    
114    /**
115     * Retrieves all name of the ancestors of the current tag.
116     * @param tag the current tag
117     * @param includeCurrent true to include the current tag itself
118     * @return the set of ancestor tag names
119     */
120    public static Set<String> getAncestorNames(Tag tag, boolean includeCurrent)
121    {
122        Set<Tag> ancestors = _getAncestors(tag, includeCurrent, null);
123        Set<String> ancestorNames = new HashSet<>();
124        
125        // Tag to tag names
126        for (Tag ancestor : ancestors)
127        {
128            ancestorNames.add(ancestor.getName());
129        }
130        
131        return ancestorNames;
132    }
133}