001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.storage.sql.coremodel;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import org.nuxeo.ecm.core.api.repository.FulltextConfiguration;
025import org.nuxeo.ecm.core.api.repository.Repository;
026import org.nuxeo.ecm.core.api.repository.RepositoryManager;
027import org.nuxeo.ecm.core.repository.RepositoryFactory;
028import org.nuxeo.ecm.core.repository.RepositoryService;
029import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor;
030import org.nuxeo.ecm.core.storage.sql.RepositoryImpl;
031import org.nuxeo.ecm.core.storage.sql.RepositoryManagement;
032import org.nuxeo.ecm.core.storage.sql.VCSRepositoryFactory;
033import org.nuxeo.runtime.api.Framework;
034import org.nuxeo.runtime.model.ComponentContext;
035import org.nuxeo.runtime.model.ComponentInstance;
036import org.nuxeo.runtime.model.DefaultComponent;
037import org.nuxeo.runtime.model.SimpleContributionRegistry;
038
039/**
040 * Service holding the configuration for VCS repositories.
041 *
042 * @since 5.9.3
043 */
044public class SQLRepositoryService extends DefaultComponent {
045
046    private static final String XP_REPOSITORY = "repository";
047
048    protected RepositoryDescriptorRegistry registry = new RepositoryDescriptorRegistry();
049
050    protected static class RepositoryDescriptorRegistry extends SimpleContributionRegistry<RepositoryDescriptor> {
051
052        @Override
053        public String getContributionId(RepositoryDescriptor contrib) {
054            return contrib.name;
055        }
056
057        @Override
058        public RepositoryDescriptor clone(RepositoryDescriptor orig) {
059            return new RepositoryDescriptor(orig);
060        }
061
062        @Override
063        public void merge(RepositoryDescriptor src, RepositoryDescriptor dst) {
064            dst.merge(src);
065        }
066
067        @Override
068        public boolean isSupportingMerge() {
069            return true;
070        }
071
072        public void clear() {
073            currentContribs.clear();
074        }
075
076        public RepositoryDescriptor getRepositoryDescriptor(String id) {
077            return getCurrentContribution(id);
078        }
079
080        public List<String> getRepositoryIds() {
081            return new ArrayList<>(currentContribs.keySet());
082        }
083    }
084
085    @Override
086    public void activate(ComponentContext context) {
087        registry.clear();
088    }
089
090    @Override
091    public void deactivate(ComponentContext context) {
092        registry.clear();
093    }
094
095    @Override
096    public void registerContribution(Object contrib, String xpoint, ComponentInstance contributor) {
097        if (XP_REPOSITORY.equals(xpoint)) {
098            addContribution((RepositoryDescriptor) contrib);
099        } else {
100            throw new RuntimeException("Unknown extension point: " + xpoint);
101        }
102    }
103
104    @Override
105    public void unregisterContribution(Object contrib, String xpoint, ComponentInstance contributor) {
106        if (XP_REPOSITORY.equals(xpoint)) {
107            removeContribution((RepositoryDescriptor) contrib);
108        } else {
109            throw new RuntimeException("Unknown extension point: " + xpoint);
110        }
111    }
112
113    protected void addContribution(RepositoryDescriptor descriptor) {
114        registry.addContribution(descriptor);
115        updateRegistration(descriptor.name);
116    }
117
118    protected void removeContribution(RepositoryDescriptor descriptor) {
119        registry.removeContribution(descriptor);
120        updateRegistration(descriptor.name);
121    }
122
123    /**
124     * Update repository registration in high-level repository service.
125     */
126    protected void updateRegistration(String repositoryName) {
127        RepositoryManager repositoryManager = Framework.getService(RepositoryManager.class);
128        RepositoryDescriptor descriptor = registry.getRepositoryDescriptor(repositoryName);
129        if (descriptor == null) {
130            // last contribution removed
131            repositoryManager.removeRepository(repositoryName);
132            return;
133        }
134        // extract label, isDefault
135        // and pass it to high-level registry
136        RepositoryFactory repositoryFactory = new VCSRepositoryFactory(repositoryName);
137        Repository repository = new Repository(repositoryName, descriptor.label, descriptor.isDefault(),
138                descriptor.isHeadless(), repositoryFactory, descriptor.pool);
139        repositoryManager.addRepository(repository);
140    }
141
142    public RepositoryDescriptor getRepositoryDescriptor(String name) {
143        return registry.getRepositoryDescriptor(name);
144    }
145
146    /**
147     * Gets the list of SQL repository names.
148     *
149     * @return the list of SQL repository names
150     * @since 5.9.5
151     */
152    public List<String> getRepositoryNames() {
153        return registry.getRepositoryIds();
154    }
155
156    /**
157     * Gets the low-level SQL Repository of the given name.
158     *
159     * @param repositoryName the repository name
160     * @return the repository
161     * @since 5.9.5
162     */
163    public RepositoryManagement getRepository(String repositoryName) {
164        RepositoryService repositoryService = Framework.getService(RepositoryService.class);
165        org.nuxeo.ecm.core.model.Repository repository = repositoryService.getRepository(repositoryName);
166        if (repository == null) {
167            throw new RuntimeException("Unknown repository: " + repositoryName);
168        }
169        if (repository instanceof org.nuxeo.ecm.core.storage.sql.Repository) {
170            // (JCA) ConnectionFactoryImpl already implements Repository
171            return (org.nuxeo.ecm.core.storage.sql.Repository) repository;
172        } else {
173            throw new RuntimeException("Unknown repository class: " + repository.getClass().getName());
174        }
175    }
176
177    public RepositoryImpl getRepositoryImpl(String repositoryName) {
178        return (RepositoryImpl) getRepository(repositoryName);
179    }
180
181    /**
182     * Gets the repositories as a list of {@link RepositoryManagement} objects.
183     *
184     * @since 5.9.5
185     * @return a list of {@link RepositoryManagement}
186     */
187    public List<RepositoryManagement> getRepositories() {
188        List<RepositoryManagement> repositories = new ArrayList<>();
189        for (String repositoryName : getRepositoryNames()) {
190            repositories.add(getRepository(repositoryName));
191        }
192        return repositories;
193    }
194
195    public FulltextConfiguration getFulltextConfiguration(String repositoryName) {
196        return getRepositoryImpl(repositoryName).getModel().getFulltextConfiguration();
197    }
198
199}