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.settings;
016    
017    import com.liferay.portal.NoSuchPortletItemException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.resource.ResourceRetriever;
020    import com.liferay.portal.kernel.resource.manager.ClassLoaderResourceManager;
021    import com.liferay.portal.kernel.resource.manager.ResourceManager;
022    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
023    import com.liferay.portal.kernel.settings.ArchivedSettings;
024    import com.liferay.portal.kernel.settings.FallbackKeys;
025    import com.liferay.portal.kernel.settings.FallbackSettings;
026    import com.liferay.portal.kernel.settings.PortletPreferencesSettings;
027    import com.liferay.portal.kernel.settings.Settings;
028    import com.liferay.portal.kernel.settings.SettingsFactory;
029    import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
030    import com.liferay.portal.kernel.util.PropsUtil;
031    import com.liferay.portal.model.Group;
032    import com.liferay.portal.model.Layout;
033    import com.liferay.portal.model.PortletConstants;
034    import com.liferay.portal.model.PortletItem;
035    import com.liferay.portal.security.auth.PrincipalThreadLocal;
036    import com.liferay.portal.service.GroupLocalServiceUtil;
037    import com.liferay.portal.service.PortalPreferencesLocalServiceUtil;
038    import com.liferay.portal.service.PortletItemLocalServiceUtil;
039    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
040    import com.liferay.portal.util.PortletKeys;
041    
042    import java.io.InputStream;
043    
044    import java.util.ArrayList;
045    import java.util.Collections;
046    import java.util.List;
047    import java.util.Map;
048    import java.util.Properties;
049    import java.util.concurrent.ConcurrentHashMap;
050    import java.util.concurrent.ConcurrentMap;
051    
052    import javax.portlet.PortletPreferences;
053    
054    /**
055     * @author Raymond Aug??
056     * @author Jorge Ferrer
057     */
058    @DoPrivileged
059    public class SettingsFactoryImpl implements SettingsFactory {
060    
061            @Override
062            public void clearCache() {
063                    _portletPropertiesMap.clear();
064                    _propertiesMap.clear();
065            }
066    
067            @Override
068            public Settings getCompanyServiceSettings(
069                    long companyId, String serviceName) {
070    
071                    return applyFallbackKeys(
072                            serviceName, getCompanySettings(companyId, serviceName));
073            }
074    
075            @Override
076            public Settings getGroupServiceCompanyDefaultSettings(
077                    long companyId, String serviceName) {
078    
079                    return applyFallbackKeys(
080                            serviceName,
081                            new PortletPreferencesSettings(
082                                    getCompanyPortletPreferences(companyId, serviceName)));
083            }
084    
085            @Override
086            public Settings getGroupServiceSettings(long groupId, String serviceName)
087                    throws PortalException {
088    
089                    return applyFallbackKeys(
090                            serviceName, getGroupSettings(groupId, serviceName));
091            }
092    
093            @Override
094            public List<String> getMultiValuedKeys(String settingsId) {
095                    settingsId = PortletConstants.getRootPortletId(settingsId);
096    
097                    List<String> multiValuedKeys = _multiValuedKeysMap.get(settingsId);
098    
099                    if (multiValuedKeys == null) {
100                            throw new IllegalStateException(
101                                    "No multi valued keys found for settings ID " + settingsId);
102                    }
103    
104                    return multiValuedKeys;
105            }
106    
107            @Override
108            public ArchivedSettings getPortletInstanceArchivedSettings(
109                            long groupId, String portletId, String name)
110                    throws PortalException {
111    
112                    PortletItem portletItem = null;
113    
114                    try {
115                            portletItem = PortletItemLocalServiceUtil.getPortletItem(
116                                    groupId, name, portletId, PortletPreferences.class.getName());
117                    }
118                    catch (NoSuchPortletItemException nspie) {
119                            long userId = PrincipalThreadLocal.getUserId();
120    
121                            portletItem = PortletItemLocalServiceUtil.updatePortletItem(
122                                    userId, groupId, name, portletId,
123                                    PortletPreferences.class.getName());
124                    }
125    
126                    return new ArchivedSettingsImpl(portletItem);
127            }
128    
129            @Override
130            public List<ArchivedSettings> getPortletInstanceArchivedSettingsList(
131                    long groupId, String portletId) {
132    
133                    List<ArchivedSettings> archivedSettingsList =
134                            new ArrayList<ArchivedSettings>();
135    
136                    List<PortletItem> portletItems =
137                            PortletItemLocalServiceUtil.getPortletItems(
138                                    groupId, portletId,
139                                    com.liferay.portal.model.PortletPreferences.class.getName());
140    
141                    for (PortletItem portletItem : portletItems) {
142                            archivedSettingsList.add(new ArchivedSettingsImpl(portletItem));
143                    }
144    
145                    return archivedSettingsList;
146            }
147    
148            @Override
149            public Settings getPortletInstanceCompanyDefaultSettings(
150                    long companyId, String portletId) {
151    
152                    return applyFallbackKeys(
153                            PortletConstants.getRootPortletId(portletId),
154                            new PortletPreferencesSettings(
155                                    getCompanyPortletPreferences(companyId, portletId)));
156            }
157    
158            @Override
159            public Settings getPortletInstanceGroupDefaultSettings(
160                            long groupId, String portletId)
161                    throws PortalException {
162    
163                    Group group = GroupLocalServiceUtil.getGroup(groupId);
164    
165                    return applyFallbackKeys(
166                            PortletConstants.getRootPortletId(portletId),
167                            new PortletPreferencesSettings(
168                                    getGroupPortletPreferences(
169                                            group.getCompanyId(), groupId, portletId)));
170            }
171    
172            @Override
173            public Settings getPortletInstanceSettings(Layout layout, String portletId)
174                    throws PortalException {
175    
176                    return applyFallbackKeys(
177                            PortletConstants.getRootPortletId(portletId),
178                            new PortletPreferencesSettings(
179                                    getPortletInstancePortletPreferences(layout, portletId),
180                                    getGroupSettings(layout.getGroupId(), portletId)));
181            }
182    
183            @Override
184            public void registerSettingsMetadata(
185                    String settingsId, FallbackKeys fallbackKeys,
186                    String[] multiValuedKeysArray, ResourceManager resourceManager) {
187    
188                    settingsId = PortletConstants.getRootPortletId(settingsId);
189    
190                    if (_multiValuedKeysMap.get(settingsId) != null) {
191                            throw new IllegalStateException(
192                                    "Unable to overwrite multi valued keys for " + settingsId);
193                    }
194    
195                    _fallbackKeysMap.put(settingsId, fallbackKeys);
196    
197                    List<String> multiValuedKeysList = new ArrayList<String>();
198    
199                    Collections.addAll(multiValuedKeysList, multiValuedKeysArray);
200    
201                    multiValuedKeysList = Collections.unmodifiableList(multiValuedKeysList);
202    
203                    _multiValuedKeysMap.put(settingsId, multiValuedKeysList);
204    
205                    _resourceManagers.put(settingsId, resourceManager);
206            }
207    
208            protected Settings applyFallbackKeys(String settingsId, Settings settings) {
209                    if (settings instanceof FallbackKeys) {
210                            return settings;
211                    }
212    
213                    FallbackKeys fallbackKeys = _fallbackKeysMap.get(settingsId);
214    
215                    if (fallbackKeys != null) {
216                            settings = new FallbackSettings(settings, fallbackKeys);
217                    }
218    
219                    return settings;
220            }
221    
222            protected PortletPreferences getCompanyPortletPreferences(
223                    long companyId, String settingsId) {
224    
225                    return PortletPreferencesLocalServiceUtil.getStrictPreferences(
226                            companyId, companyId, PortletKeys.PREFS_OWNER_TYPE_COMPANY, 0,
227                            settingsId);
228            }
229    
230            protected Settings getCompanySettings(long companyId, String settingsId) {
231                    return new PortletPreferencesSettings(
232                            getCompanyPortletPreferences(companyId, settingsId),
233                            getPortalPreferencesSettings(companyId, settingsId));
234            }
235    
236            protected PortletPreferences getGroupPortletPreferences(
237                    long companyId, long groupId, String settingsId) {
238    
239                    return PortletPreferencesLocalServiceUtil.getStrictPreferences(
240                            companyId, groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP, 0,
241                            settingsId);
242            }
243    
244            protected Settings getGroupSettings(long groupId, String settingsId)
245                    throws PortalException {
246    
247                    Group group = GroupLocalServiceUtil.getGroup(groupId);
248    
249                    long companyId = group.getCompanyId();
250    
251                    return new PortletPreferencesSettings(
252                            getGroupPortletPreferences(companyId, groupId, settingsId),
253                            getCompanySettings(companyId, settingsId));
254            }
255    
256            protected PortletPreferences getPortalPreferences(long companyId) {
257                    return PortalPreferencesLocalServiceUtil.getPreferences(
258                            companyId, PortletKeys.PREFS_OWNER_TYPE_COMPANY);
259            }
260    
261            protected PortletPreferencesSettings getPortalPreferencesSettings(
262                    long companyId, String settingsId) {
263    
264                    return new PortletPreferencesSettings(
265                            getPortalPreferences(companyId),
266                            getPortletPropertiesSettings(settingsId));
267            }
268    
269            protected Properties getPortalProperties(String settingsId) {
270                    Properties portalProperties = _propertiesMap.get(settingsId);
271    
272                    if (portalProperties != null) {
273                            return portalProperties;
274                    }
275    
276                    portalProperties = PropsUtil.getProperties();
277    
278                    _propertiesMap.put(settingsId, portalProperties);
279    
280                    return portalProperties;
281            }
282    
283            protected PropertiesSettings getPortalPropertiesSettings(
284                    String settingsId) {
285    
286                    return new PropertiesSettings(
287                            getPortalProperties(settingsId),
288                            new ClassLoaderResourceManager(
289                                    PortalClassLoaderUtil.getClassLoader()));
290            }
291    
292            protected PortletPreferences getPortletInstancePortletPreferences(
293                    Layout layout, String portletId) {
294    
295                    long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
296                    int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
297    
298                    if (PortletConstants.hasUserId(portletId)) {
299                            ownerId = PortletConstants.getUserId(portletId);
300                            ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
301                    }
302    
303                    return PortletPreferencesLocalServiceUtil.getStrictPreferences(
304                            layout.getCompanyId(), ownerId, ownerType, layout.getPlid(),
305                            portletId);
306            }
307    
308            protected Properties getPortletProperties(
309                    String settingsId, ResourceManager resourceManager) {
310    
311                    Properties properties = _portletPropertiesMap.get(settingsId);
312    
313                    if (properties != null) {
314                            return properties;
315                    }
316    
317                    properties = new Properties();
318    
319                    if (resourceManager == null) {
320                            return properties;
321                    }
322    
323                    ResourceRetriever resourceRetriever =
324                            resourceManager.getResourceRetriever("portlet.properties");
325    
326                    InputStream inputStream = resourceRetriever.getInputStream();
327    
328                    try {
329                            properties.load(inputStream);
330                    }
331                    catch (Exception e) {
332                    }
333    
334                    _portletPropertiesMap.put(settingsId, properties);
335    
336                    return properties;
337            }
338    
339            protected PropertiesSettings getPortletPropertiesSettings(
340                    String settingsId) {
341    
342                    ResourceManager resourceManager = getResourceManager(settingsId);
343    
344                    return new PropertiesSettings(
345                            getPortletProperties(settingsId, resourceManager), resourceManager,
346                            getPortalPropertiesSettings(settingsId));
347            }
348    
349            protected ResourceManager getResourceManager(String settingsId) {
350                    settingsId = PortletConstants.getRootPortletId(settingsId);
351    
352                    return _resourceManagers.get(settingsId);
353            }
354    
355            private final ConcurrentMap<String, FallbackKeys> _fallbackKeysMap =
356                    new ConcurrentHashMap<String, FallbackKeys>();
357            private final ConcurrentMap<String, List<String>> _multiValuedKeysMap =
358                    new ConcurrentHashMap<String, List<String>>();
359            private final Map<String, Properties> _portletPropertiesMap =
360                    new ConcurrentHashMap<String, Properties>();
361            private final Map<String, Properties> _propertiesMap =
362                    new ConcurrentHashMap<String, Properties>();
363            private final ConcurrentMap<String, ResourceManager> _resourceManagers =
364                    new ConcurrentHashMap<String, ResourceManager>();
365    
366    }