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.xmlrpc;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.xmlrpc.Method;
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.ServiceRegistrationMap;
027    
028    import java.util.HashMap;
029    import java.util.Map;
030    import java.util.concurrent.ConcurrentHashMap;
031    
032    /**
033     * @author Raymond Aug??
034     */
035    public class XmlRpcMethodUtil {
036    
037            public static Method getMethod(String token, String methodName) {
038                    return _instance._getMethod(token, methodName);
039            }
040    
041            public static void registerMethod(Method method) {
042                    if (method == null) {
043                            return;
044                    }
045    
046                    _instance._registerMethod(method);
047            }
048    
049            public static void unregisterMethod(Method method) {
050                    if (method == null) {
051                            return;
052                    }
053    
054                    _instance._unregisterMethod(method);
055            }
056    
057            protected Method _getMethod(String token, String methodName) {
058                    Method method = null;
059    
060                    Map<String, Method> methods = _methodRegistry.get(token);
061    
062                    if (methods != null) {
063                            method = methods.get(methodName);
064                    }
065    
066                    return method;
067            }
068    
069            private XmlRpcMethodUtil() {
070                    Registry registry = RegistryUtil.getRegistry();
071    
072                    _serviceTracker = registry.trackServices(
073                            Method.class, new MethodServiceTrackerCustomizer());
074    
075                    _serviceTracker.open();
076            }
077    
078            private void _registerMethod(Method method) {
079                    Registry registry = RegistryUtil.getRegistry();
080    
081                    ServiceRegistration<Method> serviceRegistration =
082                            registry.registerService(Method.class, method);
083    
084                    _serviceRegistrations.put(method, serviceRegistration);
085            }
086    
087            private void _unregisterMethod(Method method) {
088                    ServiceRegistration<Method> serviceRegistration =
089                            _serviceRegistrations.remove(method);
090    
091                    if (serviceRegistration != null) {
092                            serviceRegistration.unregister();
093                    }
094            }
095    
096            private static final Log _log = LogFactoryUtil.getLog(
097                    XmlRpcMethodUtil.class);
098    
099            private static final XmlRpcMethodUtil _instance = new XmlRpcMethodUtil();
100    
101            private final Map<String, Map<String, Method>> _methodRegistry =
102                    new ConcurrentHashMap<String, Map<String, Method>>();
103            private final ServiceRegistrationMap<Method> _serviceRegistrations =
104                    new ServiceRegistrationMap<Method>();
105            private final ServiceTracker<Method, Method> _serviceTracker;
106    
107            private class MethodServiceTrackerCustomizer
108                    implements ServiceTrackerCustomizer<Method, Method> {
109    
110                    @Override
111                    public Method addingService(ServiceReference<Method> serviceReference) {
112                            Registry registry = RegistryUtil.getRegistry();
113    
114                            Method method = registry.getService(serviceReference);
115    
116                            String token = method.getToken();
117    
118                            Map<String, Method> methods = _methodRegistry.get(token);
119    
120                            if (methods == null) {
121                                    methods = new HashMap<String, Method>();
122    
123                                    _methodRegistry.put(token, methods);
124                            }
125    
126                            String methodName = method.getMethodName();
127    
128                            Method registeredMethod = methods.get(methodName);
129    
130                            if (registeredMethod != null) {
131                                    if (_log.isWarnEnabled()) {
132                                            _log.warn(
133                                                    "There is already an XML-RPC method registered with " +
134                                                            "name " + methodName + " at " + token);
135                                    }
136                            }
137                            else {
138                                    methods.put(methodName, method);
139                            }
140    
141                            return method;
142                    }
143    
144                    @Override
145                    public void modifiedService(
146                            ServiceReference<Method> serviceReference, Method method) {
147                    }
148    
149                    @Override
150                    public void removedService(
151                            ServiceReference<Method> serviceReference, Method method) {
152    
153                            Registry registry = RegistryUtil.getRegistry();
154    
155                            registry.ungetService(serviceReference);
156    
157                            String token = method.getToken();
158    
159                            Map<String, Method> methods = _methodRegistry.get(token);
160    
161                            if (methods == null) {
162                                    return;
163                            }
164    
165                            String methodName = method.getMethodName();
166    
167                            methods.remove(methodName);
168    
169                            if (methods.isEmpty()) {
170                                    _methodRegistry.remove(token);
171                            }
172                    }
173    
174            }
175    
176    }