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.repository.registry;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.repository.DocumentRepository;
019    import com.liferay.portal.kernel.repository.LocalRepository;
020    import com.liferay.portal.kernel.repository.Repository;
021    import com.liferay.portal.kernel.repository.RepositoryConfiguration;
022    import com.liferay.portal.kernel.repository.RepositoryFactory;
023    import com.liferay.portal.kernel.repository.capabilities.Capability;
024    import com.liferay.portal.kernel.repository.capabilities.ConfigurationCapability;
025    import com.liferay.portal.kernel.repository.capabilities.RepositoryEventTriggerCapability;
026    import com.liferay.portal.kernel.repository.event.RepositoryEventAware;
027    import com.liferay.portal.kernel.repository.event.RepositoryEventListener;
028    import com.liferay.portal.kernel.repository.event.RepositoryEventTrigger;
029    import com.liferay.portal.kernel.repository.event.RepositoryEventType;
030    import com.liferay.portal.kernel.repository.registry.RepositoryDefiner;
031    import com.liferay.portal.kernel.repository.registry.RepositoryEventRegistry;
032    import com.liferay.portal.kernel.repository.registry.RepositoryFactoryRegistry;
033    import com.liferay.portal.repository.InitializedLocalRepository;
034    import com.liferay.portal.repository.InitializedRepository;
035    import com.liferay.portal.repository.capabilities.CapabilityLocalRepository;
036    import com.liferay.portal.repository.capabilities.CapabilityRepository;
037    import com.liferay.portal.repository.capabilities.ConfigurationCapabilityImpl;
038    import com.liferay.portal.repository.capabilities.LiferayRepositoryEventTriggerCapability;
039    import com.liferay.portal.repository.capabilities.util.RepositoryServiceAdapter;
040    
041    import java.util.Locale;
042    import java.util.Map;
043    import java.util.concurrent.ConcurrentHashMap;
044    
045    /**
046     * @author Adolfo P??rez
047     */
048    public class RepositoryClassDefinition
049            implements RepositoryFactory, RepositoryFactoryRegistry {
050    
051            public static final RepositoryClassDefinition fromRepositoryDefiner(
052                    RepositoryDefiner repositoryDefiner) {
053    
054                    DefaultRepositoryEventRegistry defaultRepositoryEventRegistry =
055                            new DefaultRepositoryEventRegistry(null);
056    
057                    RepositoryClassDefinition repositoryClassDefinition =
058                            new RepositoryClassDefinition(
059                                    repositoryDefiner, defaultRepositoryEventRegistry);
060    
061                    repositoryDefiner.registerRepositoryFactory(repositoryClassDefinition);
062                    repositoryDefiner.registerRepositoryEventListeners(
063                            defaultRepositoryEventRegistry);
064    
065                    return repositoryClassDefinition;
066            }
067    
068            @Override
069            public LocalRepository createLocalRepository(long repositoryId)
070                    throws PortalException {
071    
072                    if (_localRepositories.containsKey(repositoryId)) {
073                            return _localRepositories.get(repositoryId);
074                    }
075    
076                    InitializedLocalRepository initializedLocalRepository =
077                            new InitializedLocalRepository();
078    
079                    DefaultCapabilityRegistry defaultCapabilityRegistry =
080                            new DefaultCapabilityRegistry(initializedLocalRepository);
081    
082                    _repositoryDefiner.registerCapabilities(defaultCapabilityRegistry);
083    
084                    DefaultRepositoryEventRegistry defaultRepositoryEventRegistry =
085                            new DefaultRepositoryEventRegistry(_rootRepositoryEventTrigger);
086    
087                    setUpCommonCapabilities(
088                            initializedLocalRepository, defaultCapabilityRegistry,
089                            defaultRepositoryEventRegistry);
090    
091                    defaultCapabilityRegistry.registerCapabilityRepositoryEvents(
092                            defaultRepositoryEventRegistry);
093    
094                    LocalRepository localRepository =
095                            _repositoryFactory.createLocalRepository(repositoryId);
096    
097                    LocalRepository wrappedLocalRepository =
098                            defaultCapabilityRegistry.invokeCapabilityWrappers(localRepository);
099    
100                    CapabilityLocalRepository capabilityLocalRepository =
101                            new CapabilityLocalRepository(
102                                    wrappedLocalRepository, defaultCapabilityRegistry,
103                                    defaultRepositoryEventRegistry);
104    
105                    initializedLocalRepository.setDocumentRepository(
106                            capabilityLocalRepository);
107    
108                    _localRepositories.put(repositoryId, capabilityLocalRepository);
109    
110                    return capabilityLocalRepository;
111            }
112    
113            @Override
114            public Repository createRepository(long repositoryId)
115                    throws PortalException {
116    
117                    if (_repositories.containsKey(repositoryId)) {
118                            return _repositories.get(repositoryId);
119                    }
120    
121                    InitializedRepository initializedRepository =
122                            new InitializedRepository();
123    
124                    DefaultCapabilityRegistry defaultCapabilityRegistry =
125                            new DefaultCapabilityRegistry(initializedRepository);
126    
127                    _repositoryDefiner.registerCapabilities(defaultCapabilityRegistry);
128    
129                    DefaultRepositoryEventRegistry defaultRepositoryEventRegistry =
130                            new DefaultRepositoryEventRegistry(_rootRepositoryEventTrigger);
131    
132                    setUpCommonCapabilities(
133                            initializedRepository, defaultCapabilityRegistry,
134                            defaultRepositoryEventRegistry);
135    
136                    Repository repository = _repositoryFactory.createRepository(
137                            repositoryId);
138    
139                    defaultCapabilityRegistry.registerCapabilityRepositoryEvents(
140                            defaultRepositoryEventRegistry);
141    
142                    Repository wrappedRepository =
143                            defaultCapabilityRegistry.invokeCapabilityWrappers(repository);
144    
145                    CapabilityRepository capabilityRepository = new CapabilityRepository(
146                            wrappedRepository, defaultCapabilityRegistry,
147                            defaultRepositoryEventRegistry);
148    
149                    initializedRepository.setDocumentRepository(capabilityRepository);
150    
151                    _repositories.put(repositoryId, capabilityRepository);
152    
153                    return capabilityRepository;
154            }
155    
156            public String getClassName() {
157                    return _repositoryDefiner.getClassName();
158            }
159    
160            public RepositoryConfiguration getRepositoryConfiguration() {
161                    return _repositoryDefiner.getRepositoryConfiguration();
162            }
163    
164            public String getRepositoryTypeLabel(Locale locale) {
165                    return _repositoryDefiner.getRepositoryTypeLabel(locale);
166            }
167    
168            public void invalidateCache() {
169                    _localRepositories.clear();
170                    _repositories.clear();
171            }
172    
173            @Override
174            public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
175                    if (_repositoryFactory != null) {
176                            throw new IllegalStateException(
177                                    "Repository factory already exists");
178                    }
179    
180                    _repositoryFactory = repositoryFactory;
181            }
182    
183            protected RepositoryClassDefinition(
184                    RepositoryDefiner repositoryDefiner,
185                    RepositoryEventTrigger rootRepositoryEventTrigger) {
186    
187                    _repositoryDefiner = repositoryDefiner;
188                    _rootRepositoryEventTrigger = rootRepositoryEventTrigger;
189            }
190    
191            protected void invalidateCachedRepository(long repositoryId) {
192                    _localRepositories.remove(repositoryId);
193                    _repositories.remove(repositoryId);
194            }
195    
196            protected void setUpCommonCapabilities(
197                    DocumentRepository documentRepository,
198                    DefaultCapabilityRegistry capabilityRegistry,
199                    RepositoryEventTrigger repositoryEventTrigger) {
200    
201                    if (!capabilityRegistry.isCapabilityProvided(
202                                    ConfigurationCapability.class)) {
203    
204                            capabilityRegistry.addExportedCapability(
205                                    ConfigurationCapability.class,
206                                    new ConfigurationCapabilityImpl(
207                                            documentRepository,
208                                            RepositoryServiceAdapter.create(documentRepository)));
209                    }
210    
211                    if (!capabilityRegistry.isCapabilityProvided(
212                                    RepositoryEventTriggerCapability.class)) {
213    
214                            capabilityRegistry.addExportedCapability(
215                                    RepositoryEventTriggerCapability.class,
216                                    new LiferayRepositoryEventTriggerCapability(
217                                            repositoryEventTrigger));
218                    }
219    
220                    capabilityRegistry.addSupportedCapability(
221                            CacheCapability.class, new CacheCapability());
222            }
223    
224            private final Map<Long, LocalRepository> _localRepositories =
225                    new ConcurrentHashMap<>();
226            private final Map<Long, Repository> _repositories =
227                    new ConcurrentHashMap<>();
228            private final RepositoryDefiner _repositoryDefiner;
229            private RepositoryFactory _repositoryFactory;
230            private final RepositoryEventTrigger _rootRepositoryEventTrigger;
231    
232            private class CacheCapability implements Capability, RepositoryEventAware {
233    
234                    @Override
235                    public void registerRepositoryEventListeners(
236                            RepositoryEventRegistry repositoryEventRegistry) {
237    
238                            repositoryEventRegistry.registerRepositoryEventListener(
239                                    RepositoryEventType.Delete.class, LocalRepository.class,
240                                    new RepositoryEventListener
241                                            <RepositoryEventType.Delete, LocalRepository>() {
242    
243                                            @Override
244                                            public void execute(LocalRepository localRepository) {
245                                                    invalidateCachedRepository(
246                                                            localRepository.getRepositoryId());
247                                            }
248    
249                                    });
250                    }
251    
252            }
253    
254    }