001/*
002 * (C) Copyright 2007 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 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.platform.comment.service;
023
024import static org.nuxeo.ecm.platform.comment.api.CommentConstants.MIGRATION_ID;
025import static org.nuxeo.ecm.platform.comment.api.CommentConstants.MIGRATION_STATE_PROPERTY;
026import static org.nuxeo.ecm.platform.comment.api.CommentConstants.MIGRATION_STATE_RELATION;
027import static org.nuxeo.ecm.platform.comment.api.CommentConstants.MIGRATION_STATE_SECURED;
028import static org.nuxeo.ecm.platform.comment.api.CommentConstants.MIGRATION_STEP_PROPERTY_TO_SECURED;
029import static org.nuxeo.ecm.platform.comment.api.CommentConstants.MIGRATION_STEP_RELATION_TO_PROPERTY;
030
031import org.apache.commons.logging.Log;
032import org.apache.commons.logging.LogFactory;
033import org.nuxeo.ecm.platform.comment.api.CommentManager;
034import org.nuxeo.ecm.platform.comment.impl.BridgeCommentManager;
035import org.nuxeo.ecm.platform.comment.impl.CommentManagerImpl;
036import org.nuxeo.ecm.platform.comment.impl.PropertyCommentManager;
037import org.nuxeo.ecm.platform.comment.impl.TreeCommentManager;
038import org.nuxeo.runtime.api.Framework;
039import org.nuxeo.runtime.migration.MigrationService;
040import org.nuxeo.runtime.model.ComponentInstance;
041import org.nuxeo.runtime.model.ComponentName;
042import org.nuxeo.runtime.model.DefaultComponent;
043
044/**
045 * @author <a href="mailto:glefter@nuxeo.com">George Lefter</a>
046 */
047public class CommentService extends DefaultComponent {
048
049    public static final String ID = "org.nuxeo.ecm.platform.comment.service.CommentService";
050
051    /** @since 10.3 */
052    public static final ComponentName NAME = new ComponentName(ID);
053
054    public static final String VERSIONING_EXTENSION_POINT_RULES = "rules";
055
056    private static final Log log = LogFactory.getLog(CommentService.class);
057
058    // @GuardedBy("this")
059    protected volatile CommentManager commentManager;
060
061    private CommentServiceConfig config;
062
063    @Override
064    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
065        if ("config".equals(extensionPoint)) {
066            config = (CommentServiceConfig) contribution;
067            log.debug("registered service config: " + config);
068        } else {
069            log.warn("unknown extension point: " + extensionPoint);
070        }
071    }
072
073    @Override
074    public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
075        // do nothing
076    }
077
078    /**
079     * @deprecated since 11.1, it's unused and {@link CommentManagerImpl} is deprecated
080     */
081    @Deprecated(since = "11.1")
082    public CommentManager getCommentManager() {
083        log.debug("getCommentManager");
084        if (commentManager == null) {
085            commentManager = new CommentManagerImpl(config);
086        }
087        return commentManager;
088    }
089
090    public CommentServiceConfig getConfig() {
091        return config;
092    }
093
094    @Override
095    @SuppressWarnings("unchecked")
096    public <T> T getAdapter(Class<T> adapter) {
097        if (adapter == CommentService.class) {
098            return adapter.cast(this);
099        } else if (commentManager == null) {
100            synchronized (this) {
101                if (commentManager == null) {
102                    commentManager = recomputeCommentManager();
103                }
104            }
105        }
106        return (T) commentManager;
107    }
108
109    // called under synchronized (this)
110    @SuppressWarnings("deprecation")
111    protected CommentManager recomputeCommentManager() {
112        MigrationService migrationService = Framework.getService(MigrationService.class);
113        MigrationService.MigrationStatus status = migrationService.getStatus(MIGRATION_ID);
114        if (status == null) {
115            throw new IllegalStateException("Unknown migration status for: " + MIGRATION_ID);
116        }
117        if (status.isRunning()) {
118            String step = status.getStep();
119            if (MIGRATION_STEP_RELATION_TO_PROPERTY.equals(step)) {
120                return new BridgeCommentManager(new CommentManagerImpl(config), new PropertyCommentManager());
121            } else if (MIGRATION_STEP_PROPERTY_TO_SECURED.equals(step)) {
122                return new BridgeCommentManager(new PropertyCommentManager(), new TreeCommentManager());
123            } else {
124                throw new IllegalStateException("Unknown migration step: " + step);
125            }
126        } else {
127            String state = status.getState();
128            if (MIGRATION_STATE_RELATION.equals(state)) {
129                return new CommentManagerImpl(config);
130            } else if (MIGRATION_STATE_PROPERTY.equals(state)) {
131                return new PropertyCommentManager();
132            } else if (MIGRATION_STATE_SECURED.equals(state)) {
133                return new TreeCommentManager();
134            } else {
135                throw new IllegalStateException("Unknown migration state: " + state);
136            }
137        }
138    }
139
140    /**
141     * Called when the migration status changes, to recompute the new service.
142     *
143     * @since 10.3
144     */
145    public void invalidateCommentManagerImplementation() {
146        synchronized (this) {
147            commentManager = recomputeCommentManager();
148        }
149    }
150
151}