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