001/*
002 * (C) Copyright 2012 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 *     Anahide Tchertchian
018 */
019package org.nuxeo.ecm.core.lifecycle.impl;
020
021import java.util.Collection;
022import java.util.HashMap;
023import java.util.HashSet;
024import java.util.Map;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.nuxeo.ecm.core.lifecycle.LifeCycle;
029import org.nuxeo.ecm.core.lifecycle.LifeCycleState;
030import org.nuxeo.ecm.core.lifecycle.extensions.LifeCycleDescriptor;
031import org.nuxeo.runtime.model.ContributionFragmentRegistry;
032
033/**
034 * Registry for life cycles
035 *
036 * @since 5.6
037 */
038public class LifeCycleRegistry extends ContributionFragmentRegistry<LifeCycleDescriptor> {
039
040    private static final Log log = LogFactory.getLog(LifeCycleRegistry.class);
041
042    protected Map<String, LifeCycle> lifeCycles = new HashMap<>();
043
044    @Override
045    public String getContributionId(LifeCycleDescriptor contrib) {
046        return contrib.getName();
047    }
048
049    @Override
050    public void contributionUpdated(String id, LifeCycleDescriptor contrib, LifeCycleDescriptor newOrigContrib) {
051        log.info("Registering lifecycle: " + contrib.getName());
052        lifeCycles.put(contrib.getName(), getLifeCycle(contrib));
053    }
054
055    @Override
056    public void contributionRemoved(String id, LifeCycleDescriptor lifeCycleDescriptor) {
057        log.info("Unregistering lifecycle: " + lifeCycleDescriptor.getName());
058        lifeCycles.remove(lifeCycleDescriptor.getName());
059    }
060
061    @Override
062    public boolean isSupportingMerge() {
063        return false;
064    }
065
066    @Override
067    public LifeCycleDescriptor clone(LifeCycleDescriptor orig) {
068        throw new UnsupportedOperationException();
069    }
070
071    @Override
072    public void merge(LifeCycleDescriptor src, LifeCycleDescriptor dst) {
073        throw new UnsupportedOperationException();
074    }
075
076    // API
077
078    public LifeCycle getLifeCycle(String name) {
079        return lifeCycles.get(name);
080    }
081
082    public Collection<LifeCycle> getLifeCycles() {
083        return lifeCycles.values();
084    }
085
086    /**
087     * Returns a life cycle instance out of the life cycle configuration.
088     */
089    public LifeCycle getLifeCycle(LifeCycleDescriptor desc) {
090        String name = desc.getName();
091        String initialStateName = desc.getInitialStateName();
092        String defaultInitialStateName = desc.getDefaultInitialStateName();
093        if (initialStateName != null) {
094            defaultInitialStateName = initialStateName;
095            log.warn(String.format("Lifecycle registration of default initial"
096                    + " state has changed, change initial=\"%s\" to "
097                    + "defaultInitial=\"%s\" in lifecyle '%s' definition", defaultInitialStateName,
098                    defaultInitialStateName, name));
099        }
100        boolean defaultInitialStateFound = false;
101        Collection<String> initialStateNames = new HashSet<>();
102        Collection<LifeCycleState> states = desc.getStates();
103        for (LifeCycleState state : states) {
104            String stateName = state.getName();
105            if (defaultInitialStateName.equals(stateName)) {
106                defaultInitialStateFound = true;
107                initialStateNames.add(stateName);
108            }
109            if (state.isInitial()) {
110                initialStateNames.add(stateName);
111            }
112        }
113        if (!defaultInitialStateFound) {
114            log.error(String.format("Default initial state %s not found on lifecycle %s", defaultInitialStateName, name));
115        }
116        return new LifeCycleImpl(name, defaultInitialStateName, initialStateNames, states, desc.getTransitions());
117    }
118
119}