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<>();
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_EMBEDDED, LayoutConstants.TYPE_LINK_TO_LAYOUT,
110                    LayoutConstants.TYPE_PANEL, LayoutConstants.TYPE_PORTLET,
111                    LayoutConstants.TYPE_URL
112            };
113    
114            private static final LayoutTypeControllerTracker _instance =
115                    new LayoutTypeControllerTracker();
116    
117            private final Map<String, LayoutTypeController>
118                    _defaultLayoutTypeControllers = new ConcurrentHashMap<>();
119            private final ConcurrentMap<String, LayoutTypeController>
120                    _layoutTypeControllers = new ConcurrentHashMap<>();
121            private final ServiceTracker <LayoutTypeController, LayoutTypeController>
122                    _serviceTracker;
123    
124            private class LayoutTypeControllerServiceTrackerCustomizer
125                    implements ServiceTrackerCustomizer
126                            <LayoutTypeController, LayoutTypeController> {
127    
128                    @Override
129                    @SuppressWarnings("unchecked")
130                    public LayoutTypeController addingService(
131                            ServiceReference<LayoutTypeController> serviceReference) {
132    
133                            Registry registry = RegistryUtil.getRegistry();
134    
135                            LayoutTypeController layoutTypeController = registry.getService(
136                                    serviceReference);
137    
138                            String type = (String)serviceReference.getProperty("layout.type");
139    
140                            _layoutTypeControllers.put(type, layoutTypeController);
141    
142                            return layoutTypeController;
143                    }
144    
145                    @Override
146                    public void modifiedService(
147                            ServiceReference<LayoutTypeController> serviceReference,
148                            LayoutTypeController layoutTypeController) {
149                    }
150    
151                    @Override
152                    public void removedService(
153                            ServiceReference<LayoutTypeController> serviceReference,
154                            LayoutTypeController layoutTypeController) {
155    
156                            Registry registry = RegistryUtil.getRegistry();
157    
158                            registry.ungetService(serviceReference);
159    
160                            String type = (String)serviceReference.getProperty("layout.type");
161    
162                            if (_defaultLayoutTypeControllers.containsKey(type)) {
163                                    _layoutTypeControllers.replace(
164                                            type, layoutTypeController,
165                                            _defaultLayoutTypeControllers.get(type));
166                            }
167                            else {
168                                    _layoutTypeControllers.remove(type);
169                            }
170                    }
171    
172            }
173    
174    }