001    /**
002     * Copyright (c) 2000-present 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.portal.struts;
016    
017    import com.liferay.portal.kernel.struts.StrutsAction;
018    import com.liferay.portal.kernel.struts.StrutsPortletAction;
019    import com.liferay.registry.Filter;
020    import com.liferay.registry.Registry;
021    import com.liferay.registry.RegistryUtil;
022    import com.liferay.registry.ServiceReference;
023    import com.liferay.registry.ServiceRegistration;
024    import com.liferay.registry.ServiceTracker;
025    import com.liferay.registry.ServiceTrackerCustomizer;
026    import com.liferay.registry.collections.StringServiceRegistrationMap;
027    
028    import java.util.HashMap;
029    import java.util.Map;
030    import java.util.concurrent.ConcurrentHashMap;
031    
032    import org.apache.struts.action.Action;
033    
034    /**
035     * @author Mika Koivisto
036     * @author Raymond Aug??
037     */
038    public class StrutsActionRegistryUtil {
039    
040            public static Action getAction(String path) {
041                    return _instance._getAction(path);
042            }
043    
044            public static Map<String, Action> getActions() {
045                    return _instance._getActions();
046            }
047    
048            public static void register(String path, StrutsAction strutsAction) {
049                    _instance._register(path, strutsAction);
050            }
051    
052            public static void register(
053                    String path, StrutsPortletAction strutsPortletAction) {
054    
055                    _instance._register(path, strutsPortletAction);
056            }
057    
058            public static void unregister(String path) {
059                    _instance._unregister(path);
060            }
061    
062            private StrutsActionRegistryUtil() {
063                    Registry registry = RegistryUtil.getRegistry();
064    
065                    Filter filter = registry.getFilter(
066                            "(&(|(objectClass=" + StrutsAction.class.getName() +
067                                    ")(objectClass=" + StrutsPortletAction.class.getName() +
068                                            "))(path=*))");
069    
070                    _serviceTracker = registry.trackServices(
071                            filter, new ActionServiceTrackerCustomizer());
072    
073                    _serviceTracker.open();
074            }
075    
076            private Action _getAction(String path) {
077                    Action action = _actions.get(path);
078    
079                    if (action != null) {
080                            return action;
081                    }
082    
083                    for (Map.Entry<String, Action> entry : _actions.entrySet()) {
084                            if (path.startsWith(entry.getKey())) {
085                                    return entry.getValue();
086                            }
087                    }
088    
089                    return null;
090            }
091    
092            private Map<String, Action> _getActions() {
093                    return _actions;
094            }
095    
096            private void _register(String path, StrutsAction strutsAction) {
097                    Registry registry = RegistryUtil.getRegistry();
098    
099                    Map<String, Object> properties = new HashMap<>();
100    
101                    properties.put("path", path);
102    
103                    ServiceRegistration<StrutsAction> serviceRegistration =
104                            registry.registerService(
105                                    StrutsAction.class, strutsAction, properties);
106    
107                    _strutsActionServiceRegistrations.put(path, serviceRegistration);
108            }
109    
110            private void _register(
111                    String path, StrutsPortletAction strutsPortletAction) {
112    
113                    Registry registry = RegistryUtil.getRegistry();
114    
115                    Map<String, Object> properties = new HashMap<>();
116    
117                    properties.put("path", path);
118    
119                    ServiceRegistration<StrutsPortletAction> serviceRegistration =
120                            registry.registerService(
121                                    StrutsPortletAction.class, strutsPortletAction, properties);
122    
123                    _strutsPortletActionServiceRegistrations.put(path, serviceRegistration);
124            }
125    
126            private void _unregister(String path) {
127                    ServiceRegistration<?> serviceRegistration =
128                            _strutsActionServiceRegistrations.remove(path);
129    
130                    if (serviceRegistration != null) {
131                            serviceRegistration.unregister();
132                    }
133    
134                    serviceRegistration = _strutsPortletActionServiceRegistrations.remove(
135                            path);
136    
137                    if (serviceRegistration != null) {
138                            serviceRegistration.unregister();
139                    }
140            }
141    
142            private static final StrutsActionRegistryUtil _instance =
143                    new StrutsActionRegistryUtil();
144    
145            private final Map<String, Action> _actions = new ConcurrentHashMap<>();
146            private final ServiceTracker<?, Action> _serviceTracker;
147            private final StringServiceRegistrationMap<StrutsAction>
148                    _strutsActionServiceRegistrations =
149                            new StringServiceRegistrationMap<>();
150            private final StringServiceRegistrationMap<StrutsPortletAction>
151                    _strutsPortletActionServiceRegistrations =
152                            new StringServiceRegistrationMap<>();
153    
154            private class ActionServiceTrackerCustomizer
155                    implements ServiceTrackerCustomizer<Object, Action> {
156    
157                    @Override
158                    public Action addingService(ServiceReference<Object> serviceReference) {
159                            Registry registry = RegistryUtil.getRegistry();
160    
161                            Object service = registry.getService(serviceReference);
162    
163                            Action action = null;
164    
165                            if (service instanceof StrutsAction) {
166                                    action = new ActionAdapter((StrutsAction)service);
167                            }
168                            else if (service instanceof StrutsPortletAction) {
169                                    action = new PortletActionAdapter((StrutsPortletAction)service);
170                            }
171    
172                            String[] paths = _getPaths(serviceReference);
173    
174                            for (String path : paths) {
175                                    _actions.put(path, action);
176                            }
177    
178                            return action;
179                    }
180    
181                    @Override
182                    public void modifiedService(
183                            ServiceReference<Object> serviceReference, Action service) {
184                    }
185    
186                    @Override
187                    public void removedService(
188                            ServiceReference<Object> serviceReference, Action service) {
189    
190                            Registry registry = RegistryUtil.getRegistry();
191    
192                            registry.ungetService(serviceReference);
193    
194                            String[] paths = _getPaths(serviceReference);
195    
196                            for (String path : paths) {
197                                    _actions.remove(path);
198                            }
199                    }
200    
201                    private String[] _getPaths(ServiceReference<Object> serviceReference) {
202                            Object object = serviceReference.getProperty("path");
203    
204                            if (object instanceof String[]) {
205                                    return (String[])object;
206                            }
207                            else {
208                                    return new String[] {(String)object};
209                            }
210                    }
211    
212            }
213    
214    }