001    package org.apache.maven.lifecycle;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.codehaus.plexus.component.annotations.Component;
023    import org.codehaus.plexus.component.annotations.Requirement;
024    import org.codehaus.plexus.logging.Logger;
025    import org.codehaus.plexus.util.StringUtils;
026    
027    import java.util.ArrayList;
028    import java.util.Arrays;
029    import java.util.HashMap;
030    import java.util.LinkedHashMap;
031    import java.util.LinkedHashSet;
032    import java.util.List;
033    import java.util.Map;
034    import java.util.Set;
035    
036    /**
037     * @since 3.0
038     * @author Jason van Zyl
039     * @author Kristian Rosenvold
040     */
041    // TODO: The configuration for the lifecycle needs to be externalized so that I can use the annotations properly for the
042    // wiring and reference and external source for the lifecycle configuration.
043    @Component( role = DefaultLifecycles.class )
044    public class DefaultLifecycles
045    {
046        public static final String[] STANDARD_LIFECYCLES = { "default", "clean", "site" };
047    
048        // @Configuration(source="org/apache/maven/lifecycle/lifecycles.xml")
049    
050        @Requirement( role = Lifecycle.class )
051        private Map<String, Lifecycle> lifecycles;
052    
053        @Requirement
054        private Logger logger;
055    
056        public DefaultLifecycles()
057        {
058        }
059    
060        public DefaultLifecycles( Map<String, Lifecycle> lifecycles, Logger logger )
061        {
062            this.lifecycles = new LinkedHashMap<String, Lifecycle>();
063            this.logger = logger;
064            this.lifecycles = lifecycles;
065        }
066    
067        public Lifecycle get( String key )
068        {
069            return getPhaseToLifecycleMap().get( key );
070        }
071    
072        /**
073         * We use this to map all phases to the lifecycle that contains it. This is used so that a user can specify the
074         * phase they want to execute and we can easily determine what lifecycle we need to run.
075         *
076         * @return A map of lifecycles, indexed on id
077         */
078        public Map<String, Lifecycle> getPhaseToLifecycleMap()
079        {
080            // If people are going to make their own lifecycles then we need to tell people how to namespace them correctly
081            // so that they don't interfere with internally defined lifecycles.
082    
083            HashMap<String, Lifecycle> phaseToLifecycleMap = new HashMap<String, Lifecycle>();
084    
085            for ( Lifecycle lifecycle : getLifeCycles() )
086            {
087                if ( logger.isDebugEnabled() )
088                {
089                    logger.debug( "Lifecycle " + lifecycle );
090                }
091    
092                for ( String phase : lifecycle.getPhases() )
093                {
094                    // The first definition wins.
095                    if ( !phaseToLifecycleMap.containsKey( phase ) )
096                    {
097                        phaseToLifecycleMap.put( phase, lifecycle );
098                    }
099                    else
100                    {
101                        Lifecycle original = phaseToLifecycleMap.get( phase );
102                        logger.warn( "Duplicated lifecycle phase " + phase + ". Defined in " + original.getId()
103                            + " but also in " + lifecycle.getId() );
104                    }
105                }
106            }
107    
108            return phaseToLifecycleMap;
109        }
110    
111        public List<Lifecycle> getLifeCycles()
112        {
113            // ensure canonical order of standard lifecycles
114            Map<String, Lifecycle> lifecycles = new LinkedHashMap<String, Lifecycle>( this.lifecycles );
115    
116            LinkedHashSet<String> lifecycleNames = new LinkedHashSet<String>( Arrays.asList( STANDARD_LIFECYCLES ) );
117            lifecycleNames.addAll( lifecycles.keySet() );
118    
119            ArrayList<Lifecycle> result = new ArrayList<Lifecycle>();
120            for ( String name : lifecycleNames )
121            {
122                result.add( lifecycles.get( name ) );
123            }
124    
125            return result;
126        }
127    
128        public String getLifecyclePhaseList()
129        {
130            Set<String> phases = new LinkedHashSet<String>();
131    
132            for ( Lifecycle lifecycle : lifecycles.values() )
133            {
134                phases.addAll( lifecycle.getPhases() );
135            }
136    
137            return StringUtils.join( phases.iterator(), ", " );
138        }
139    
140    }