/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.rendering.internal.macro;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

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

import org.xwiki.component.annotation.Component;
import org.xwiki.rendering.macro.MacroCategoryManager;
import org.xwiki.rendering.macro.MacroId;
import org.xwiki.rendering.macro.MacroLookupException;
import org.xwiki.rendering.macro.MacroManager;
import org.xwiki.rendering.syntax.Syntax;
import org.xwiki.rendering.transformation.macro.MacroTransformationConfiguration;

/**
 * Default implementation of {@link org.xwiki.rendering.macro.MacroCategoryManager}.
 *
 * @version $Id$
 * @since 2.0M3
 */
@Component
@Singleton
public class DefaultMacroCategoryManager implements MacroCategoryManager
{
    /**
     * Used to get macro categories defined by the user (if any).
     */
    @Inject
    private MacroTransformationConfiguration configuration;

    /**
     * Macro manager component used to check the existence of macros.
     */
    @Inject
    private MacroManager macroManager;

    /**
     * Internal help class to be able to search Macros matching a Macro Id.
     */
    private interface MacroMatcher
    {
        /**
         * @param macroId the macro Id to match
         * @return true if the concerned macro matches the macro Id
         */
        boolean match(MacroId macroId);
    }

    @Override
    public Set<String> getMacroCategories() throws MacroLookupException
    {
        return getMacroCategories(null);
    }

    @Override
    public Set<String> getMacroCategories(final Syntax syntax) throws MacroLookupException
    {
        Set<String> categories = getMacroIdsByCategory(new MacroMatcher()
        {
            @Override
            public boolean match(MacroId macroId)
            {
                // True if the macroId has no syntax or if it has one it has to match the passed syntax
                return syntax == null || macroId.getSyntax() == null || macroId.getSyntax() == syntax;
            }
        }).keySet();
        return Collections.unmodifiableSet(categories);
    }

    @Override
    public Set<MacroId> getMacroIds(String category) throws MacroLookupException
    {
        return getMacroIds(category, null);
    }

    @Override
    public Set<MacroId> getMacroIds(String category, final Syntax syntax) throws MacroLookupException
    {
        Set<MacroId> macros = getMacroIdsByCategory(new MacroMatcher()
        {
            @Override
            public boolean match(MacroId macroId)
            {
                // True if the macroId has no syntax or if it has one it has to match the passed syntax
                return syntax == null || macroId.getSyntax() == null || macroId.getSyntax().equals(syntax);
            }
        }).get(category);
        return (null != macros) ? Collections.unmodifiableSet(macros) : Collections.<MacroId>emptySet();
    }

    /**
     * @param matcher a macro name matcher to be able to filter macros, used to filter macros for a given syntax
     * @return macro names grouped by category, including the 'null' macro category.
     * @exception MacroLookupException if any error occurs when getting macros ids by category
     */
    private Map<String, Set<MacroId>> getMacroIdsByCategory(MacroMatcher matcher) throws MacroLookupException
    {
        Map<String, Set<MacroId>> result = new HashMap<String, Set<MacroId>>();

        // Find all registered macro ids
        Set<MacroId> macroIds = this.macroManager.getMacroIds();

        // Loop through all the macro ids and categorize them.
        Properties categories = this.configuration.getCategories();
        for (MacroId macroId : macroIds) {
            if (matcher.match(macroId)) {
                // Check if this macro's category has been overwritten.
                String category = categories.getProperty(macroId.toString());

                // If not, use the default category set by macro author.
                if (category == null) {
                    category = this.macroManager.getMacro(macroId).getDescriptor().getDefaultCategory();
                }

                // Add to category. Note the category can also be null.
                Set<MacroId> ids = result.get(category);
                if (ids == null) {
                    ids = new HashSet<MacroId>();
                }
                ids.add(macroId);
                result.put(category, ids);
            }
        }

        return result;
    }
}

@@ -2685,34 +2685,42 @@
 tcher()%0A        
-%7B%0A
+    %7B%0A    
             @Ove
@@ -2717,32 +2717,36 @@
       @Override%0A
+    
             publ
@@ -2771,32 +2771,36 @@
 acroId macroId)%0A
+    
             %7B%0A  
@@ -2805,32 +2805,36 @@
                 
+    
 // True if the m
@@ -2897,32 +2897,36 @@
 e passed syntax%0A
+    
                 
@@ -3016,34 +3016,42 @@
 ax;%0A            
-%7D%0A
+    %7D%0A    
         %7D).keySe
@@ -3463,34 +3463,42 @@
 tcher()%0A        
-%7B%0A
+    %7B%0A    
             @Ove
@@ -3495,32 +3495,36 @@
       @Override%0A
+    
             publ
@@ -3549,32 +3549,36 @@
 acroId macroId)%0A
+    
             %7B%0A  
@@ -3583,32 +3583,36 @@
                 
+    
 // True if the m
@@ -3675,32 +3675,36 @@
 e passed syntax%0A
+    
                 
@@ -3799,34 +3799,42 @@
 x);%0A            
-%7D%0A
+    %7D%0A    
         %7D).get(c

Fix new checkstyle error after upgrade to 6.1.1