001/*
002 * (C) Copyright 2009-2016 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 *     Radu Darlea
018 *     Catalin Baican
019 *     Florent Guillaume
020 */
021
022package org.nuxeo.ecm.platform.tag;
023
024import static org.nuxeo.ecm.platform.tag.TagConstants.MIGRATION_ID;
025import static org.nuxeo.ecm.platform.tag.TagConstants.MIGRATION_STATE_FACETS;
026import static org.nuxeo.ecm.platform.tag.TagConstants.MIGRATION_STATE_RELATIONS;
027import static org.nuxeo.ecm.platform.tag.TagConstants.MIGRATION_STEP_RELATIONS_TO_FACETS;
028
029import org.nuxeo.runtime.api.Framework;
030import org.nuxeo.runtime.migration.MigrationService;
031import org.nuxeo.runtime.migration.MigrationService.MigrationStatus;
032import org.nuxeo.runtime.model.Component;
033import org.nuxeo.runtime.model.ComponentName;
034import org.nuxeo.runtime.model.DefaultComponent;
035
036/**
037 * the tag component.
038 */
039public class TagServiceImpl extends DefaultComponent {
040
041    public static final ComponentName NAME = new ComponentName("org.nuxeo.ecm.platform.tag.TagService");
042
043    // @GuardedBy("this")
044    protected volatile TagService tagService;
045
046    @Override
047    public int getApplicationStartedOrder() {
048        // should deploy before repository service because the tag service is indirectly used (through a listener) by
049        // the repository init handlers
050        Component component = (Component) Framework.getRuntime()
051                                                   .getComponentInstance(
052                                                           "org.nuxeo.ecm.core.repository.RepositoryServiceComponent")
053                                                   .getInstance();
054        return component.getApplicationStartedOrder() - 1;
055    }
056
057    // called under synchronized (this)
058    protected TagService recomputeTagService() {
059        MigrationService migrationService = Framework.getService(MigrationService.class);
060        MigrationStatus status = migrationService.getStatus(MIGRATION_ID);
061        if (status == null) {
062            throw new IllegalStateException("Unknown migration status for: " + MIGRATION_ID);
063        }
064        if (status.isRunning()) {
065            String step = status.getStep();
066            if (MIGRATION_STEP_RELATIONS_TO_FACETS.equals(step)) {
067                return new BridgeTagService(new RelationTagService(), new FacetedTagService());
068            } else {
069                throw new IllegalStateException("Unknown migration step: " + step);
070            }
071        } else {
072            String state = status.getState();
073            if (MIGRATION_STATE_RELATIONS.equals(state)) {
074                return new RelationTagService();
075            } else if (MIGRATION_STATE_FACETS.equals(state)) {
076                return new FacetedTagService();
077            } else {
078                throw new IllegalStateException("Unknown migration state: " + state);
079            }
080        }
081    }
082
083    @Override
084    @SuppressWarnings("unchecked")
085    public <T> T getAdapter(Class<T> adapter) {
086        if (tagService == null) {
087            synchronized (this) {
088                if (tagService == null) {
089                    tagService = recomputeTagService();
090                }
091            }
092        }
093        return (T) tagService;
094    }
095
096    /**
097     * Called when the migration status changes, to recompute the new service.
098     *
099     * @since 9.3
100     */
101    public void invalidateTagServiceImplementation() {
102        synchronized (this) {
103            tagService = recomputeTagService();
104        }
105    }
106
107}