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.util;
016    
017    import com.liferay.portal.model.Layout;
018    import com.liferay.portal.model.LayoutConstants;
019    import com.liferay.portal.model.LayoutTypeController;
020    import com.liferay.portal.model.impl.LayoutTypeControllerImpl;
021    import com.liferay.registry.Filter;
022    import com.liferay.registry.Registry;
023    import com.liferay.registry.RegistryUtil;
024    import com.liferay.registry.ServiceReference;
025    import com.liferay.registry.ServiceTracker;
026    import com.liferay.registry.ServiceTrackerCustomizer;
027    
028    import java.util.Collections;
029    import java.util.HashMap;
030    import java.util.Map;
031    import java.util.Map.Entry;
032    import java.util.Set;
033    import java.util.concurrent.ConcurrentHashMap;
034    import java.util.concurrent.ConcurrentMap;
035    
036    /**
037     * @author Raymond Aug??
038     */
039    public class LayoutTypeControllerTracker {
040    
041            public static LayoutTypeController getLayoutTypeController(Layout layout) {
042                    return getLayoutTypeController(layout.getType());
043            }
044    
045            public static LayoutTypeController getLayoutTypeController(String type) {
046                    return _instance._getLayoutTypeController(type);
047            }
048    
049            public static Map<String, LayoutTypeController> getLayoutTypeControllers() {
050                    return Collections.unmodifiableMap(_instance._layoutTypeControllers);
051            }
052    
053            public static String[] getTypes() {
054                    return _instance._getTypes();
055            }
056    
057            private LayoutTypeControllerTracker() {
058                    for (String type : _LAYOUT_TYPES) {
059                            _defaultLayoutTypeControllers.put(
060                                    type, new LayoutTypeControllerImpl(type));
061                    }
062    
063                    Registry registry = RegistryUtil.getRegistry();
064    
065                    _registerDefaults(registry);
066    
067                    Filter filter = registry.getFilter(
068                            "(&(layout.type=*)(objectClass=" +
069                                    LayoutTypeController.class.getName() + "))");
070    
071                    _serviceTracker = registry.trackServices(
072                            filter, new LayoutTypeControllerServiceTrackerCustomizer());
073    
074                    _serviceTracker.open();
075            }
076    
077            private LayoutTypeController _getLayoutTypeController(String type) {
078                    LayoutTypeController layoutTypeController = _layoutTypeControllers.get(
079                            type);
080    
081                    if (layoutTypeController != null) {
082                            return layoutTypeController;
083                    }
084    
085                    return _layoutTypeControllers.get(LayoutConstants.TYPE_PORTLET);
086            }
087    
088            private String[] _getTypes() {
089                    Set<String> types = _layoutTypeControllers.keySet();
090    
091                    return types.toArray(new String[types.size()]);
092            }
093    
094            private void _registerDefaults(Registry registry) {
095                    Set<Entry<String, LayoutTypeController>> entries =
096                            _defaultLayoutTypeControllers.entrySet();
097    
098                    for (Entry<String, LayoutTypeController> entry : entries) {
099                            Map<String, Object> properties = new HashMap<String, Object>();
100    
101                            properties.put("layout.type", entry.getKey());
102    
103                            registry.registerService(
104                                    LayoutTypeController.class, entry.getValue(), properties);
105                    }
106            }
107    
108            private static final String[] _LAYOUT_TYPES = new String[] {
109                    LayoutConstants.TYPE_CONTROL_PANEL, LayoutConstants.TYPE_EMBEDDED,
110                    LayoutConstants.TYPE_LINK_TO_LAYOUT, LayoutConstants.TYPE_PANEL,
111                    LayoutConstants.TYPE_PORTLET, LayoutConstants.TYPE_URL
112            };
113    
114            private static final LayoutTypeControllerTracker _instance =
115                    new LayoutTypeControllerTracker();
116    
117            private final Map<String, LayoutTypeController>
118                    _defaultLayoutTypeControllers =
119                            new ConcurrentHashMap<String, LayoutTypeController>();
120            private final ConcurrentMap<String, LayoutTypeController>
121                    _layoutTypeControllers =
122                            new ConcurrentHashMap<String, LayoutTypeController>();
123            private final ServiceTracker <LayoutTypeController, LayoutTypeController>
124                    _serviceTracker;
125    
126            private class LayoutTypeControllerServiceTrackerCustomizer
127                    implements ServiceTrackerCustomizer
128                            <LayoutTypeController, LayoutTypeController> {
129    
130                    @Override
131                    @SuppressWarnings("unchecked")
132                    public LayoutTypeController addingService(
133                            ServiceReference<LayoutTypeController> serviceReference) {
134    
135                            Registry registry = RegistryUtil.getRegistry();
136    
137                            LayoutTypeController layoutTypeController = registry.getService(
138                                    serviceReference);
139    
140                            String type = (String)serviceReference.getProperty("layout.type");
141    
142                            _layoutTypeControllers.put(type, layoutTypeController);
143    
144                            return layoutTypeController;
145                    }
146    
147                    @Override
148                    public void modifiedService(
149                            ServiceReference<LayoutTypeController> serviceReference,
150                            LayoutTypeController layoutTypeController) {
151                    }
152    
153                    @Override
154                    public void removedService(
155                            ServiceReference<LayoutTypeController> serviceReference,
156                            LayoutTypeController layoutTypeController) {
157    
158                            Registry registry = RegistryUtil.getRegistry();
159    
160                            registry.ungetService(serviceReference);
161    
162                            String type = (String)serviceReference.getProperty("layout.type");
163    
164                            if (_defaultLayoutTypeControllers.containsKey(type)) {
165                                    _layoutTypeControllers.replace(
166                                            type, layoutTypeController,
167                                            _defaultLayoutTypeControllers.get(type));
168                            }
169                            else {
170                                    _layoutTypeControllers.remove(type);
171                            }
172                    }
173    
174            }
175    
176    }