001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util.bridges.mvc;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.StringBundler;
020    import com.liferay.portal.kernel.util.StringPool;
021    
022    import java.util.ArrayList;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.concurrent.ConcurrentHashMap;
026    
027    import javax.portlet.PortletRequest;
028    import javax.portlet.PortletResponse;
029    
030    /**
031     * @author Michael C. Han
032     */
033    public class ActionCommandCache {
034    
035            public static final String ACTION_PACKAGE_NAME = "action.package.prefix";
036    
037            public static final ActionCommand EMPTY = new ActionCommand() {
038    
039                    public boolean processCommand(
040                            PortletRequest portletRequest, PortletResponse portletResponse) {
041    
042                            return false;
043                    }
044    
045            };
046    
047            public ActionCommandCache(String packagePrefix) {
048                    if (!packagePrefix.endsWith(StringPool.PERIOD)) {
049                            packagePrefix = packagePrefix + StringPool.PERIOD;
050                    }
051    
052                    _packagePrefix = packagePrefix;
053            }
054    
055            public ActionCommand getActionCommand(String actionCommandName) {
056                    String className = null;
057    
058                    try {
059                            ActionCommand actionCommand = _actionCommandCache.get(
060                                    actionCommandName);
061    
062                            if (actionCommand == null) {
063                                    StringBundler sb = new StringBundler(4);
064    
065                                    sb.append(_packagePrefix);
066                                    sb.append(Character.toUpperCase(actionCommandName.charAt(0)));
067                                    sb.append(
068                                            actionCommandName.substring(1, actionCommandName.length()));
069                                    sb.append(_ACTION_COMMAND_POSTFIX);
070    
071                                    className = sb.toString();
072    
073                                    actionCommand =
074                                            (ActionCommand)Class.forName(className).newInstance();
075    
076                                    _actionCommandCache.put(actionCommandName, actionCommand);
077                            }
078    
079                            return actionCommand;
080                    }
081                    catch (Exception e) {
082                            if (_log.isWarnEnabled()) {
083                                    _log.warn("Unable to instantiate ActionCommand " + className);
084                            }
085    
086                            _actionCommandCache.put(actionCommandName, EMPTY);
087    
088                            return EMPTY;
089                    }
090            }
091    
092            public List<ActionCommand> getActionCommandChain(
093                    String actionCommandChain) {
094    
095                    List<ActionCommand> actionCommands = _actionCommandChainCache.get(
096                            actionCommandChain);
097    
098                    if (actionCommands == null) {
099                            actionCommands = new ArrayList<ActionCommand>();
100    
101                            int nextSeparator = actionCommandChain.indexOf(StringPool.COMMA);
102    
103                            int currentIndex = 0;
104    
105                            while (currentIndex < actionCommandChain.length()) {
106                                    String parsedName = actionCommandChain.substring(
107                                            currentIndex, nextSeparator);
108    
109                                    ActionCommand actionCommand = getActionCommand(
110                                            parsedName);
111    
112                                    if (actionCommand != EMPTY) {
113                                            actionCommands.add(actionCommand);
114                                    }
115                                    else {
116                                            if (_log.isWarnEnabled()) {
117                                                    _log.warn(
118                                                            "Unable to find ActionCommand " +
119                                                                    actionCommandChain);
120                                            }
121                                    }
122    
123                                    currentIndex = nextSeparator + 1;
124    
125                                    nextSeparator = actionCommandChain.indexOf(
126                                            StringPool.COMMA, currentIndex);
127    
128                                    if (nextSeparator == -1) {
129                                            break;
130                                    }
131                            }
132    
133                            _actionCommandChainCache.put(actionCommandChain, actionCommands);
134                    }
135    
136                    return actionCommands;
137            }
138    
139            public boolean isEmpty() {
140                    return _actionCommandCache.isEmpty();
141            }
142    
143            private static final String _ACTION_COMMAND_POSTFIX = "ActionCommand";
144    
145            private static Log _log = LogFactoryUtil.getLog(ActionCommandCache.class);
146    
147            private Map<String, ActionCommand> _actionCommandCache =
148                    new ConcurrentHashMap<String, ActionCommand>();
149            private Map<String, List<ActionCommand>> _actionCommandChainCache =
150                    new ConcurrentHashMap<String, List<ActionCommand>>();
151            private String _packagePrefix;
152    
153    }