001package org.apache.maven.scm.provider.synergy.util;
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
022import org.apache.maven.scm.ScmException;
023import org.apache.maven.scm.log.ScmLogger;
024
025/**
026 * In some Synergy versions (ie. 6.5) closing a session results in de-selecting
027 * the current (default) task. Therefore, the maven release-plugin fails, as the
028 * Synergy commands, as implemented in the Synergy-SCM-Provider, always close
029 * their session after being executed.<br>
030 * This manager circumvents this problem by storing the last created task which
031 * causes all check outs to be associated with it. Then, when this task gets
032 * checked in, all associated files get checked in as well.
033 * 
034 * @author <a href="jan.malcomess@steria-mummert.de">Jan Malcomess</a>
035 * @since 1.5
036 */
037public class SynergyTaskManager
038{
039    /**
040     * No Synergy-Task was created yet.
041     */
042    private static final short TASK_STATE_NONE = 0;
043
044    /**
045     * The current Synergy-Task is created but not yet completed.
046     */
047    private static final short TASK_STATE_CREATED = 1;
048
049    /**
050     * The current Synergy-Task is completed.
051     */
052    private static final short TASK_STATE_COMPLETED = 2;
053
054    /**
055     * singleton instance.
056     */
057    private static final SynergyTaskManager INSTANCE = new SynergyTaskManager();
058
059    /**
060     * The number of the current Synergy-Task.
061     */
062    private int currentTaskNumber;
063
064    /**
065     * The state of the current Synergy-Task.
066     */
067    private short currentTaskState = TASK_STATE_NONE;
068
069    /**
070     * @return singleton instance.
071     */
072    public static SynergyTaskManager getInstance()
073    {
074        return INSTANCE;
075    }
076
077    /**
078     * If necessary create a new task. Otherwise return the current task.
079     * 
080     * @param logger a logger.
081     * @param synopsis short description of task.
082     * @param release release.
083     * @param defaultTask should this task become the default task?
084     * @param ccmAddr current Synergy session ID. Used to run in multi-session.
085     * @return Task number
086     * @throws ScmException
087     */
088    public int createTask( ScmLogger logger, String synopsis, String release, boolean defaultTask, String ccmAddr )
089        throws ScmException
090    {
091        if ( logger.isDebugEnabled() )
092        {
093            logger.debug( "Synergy : Entering createTask method of SynergyTaskManager" );
094        }
095        switch ( currentTaskState )
096        {
097            case TASK_STATE_CREATED:
098                if ( defaultTask )
099                {
100                    // make sure the current task is the default task
101                    if ( SynergyUtil.getDefaultTask( logger, ccmAddr ) != currentTaskNumber )
102                    {
103                        SynergyUtil.setDefaultTask( logger, currentTaskNumber, ccmAddr );
104                    }
105                }
106                break;
107            case TASK_STATE_NONE: // fall through
108            case TASK_STATE_COMPLETED:
109                currentTaskNumber = SynergyUtil.createTask( logger, synopsis, release, defaultTask, ccmAddr );
110                currentTaskState = TASK_STATE_CREATED;
111                break;
112            default:
113                throw new IllegalStateException( "Programming error: SynergyTaskManager is in unkown state." );
114        }
115        if ( logger.isDebugEnabled() )
116        {
117            logger.debug( "createTask returns " + currentTaskNumber );
118        }
119        return currentTaskNumber;
120    }
121
122    /**
123     * Check in (that is: complete) the default task. This is either the current task managed by
124     * <code>SynergyTaskManager</code> or, if none is managed, the default task.<br>
125     * In case no task has yet been created by <code>SynergyTaskManager</code> AND no default task is set, then this is
126     * an error.<br>
127     * However, if the task that was created by <code>SynergyTaskManager</code> has already been checked in AND no
128     * default task is set, then it is assumed that all files that were checked out are already checked in because
129     * checking in a task checks in all files associated with it.
130     * 
131     * @param logger a logger.
132     * @param comment a comment for checkin.
133     * @param ccmAddr current Synergy session ID. Used to run in multi-session.
134     * @throws ScmException
135     */
136    public void checkinDefaultTask( ScmLogger logger, String comment, String ccmAddr )
137        throws ScmException
138    {
139        if ( logger.isDebugEnabled() )
140        {
141            logger.debug( "Synergy : Entering checkinDefaultTask method of SynergyTaskManager" );
142        }
143        switch ( currentTaskState )
144        {
145            case TASK_STATE_NONE:
146                // if a default task is set, then check in that
147                // otherwise we have an error
148                if ( SynergyUtil.getDefaultTask( logger, ccmAddr ) != 0 )
149                {
150                    SynergyUtil.checkinDefaultTask( logger, comment, ccmAddr );
151                }
152                else
153                {
154                    throw new ScmException( "Check in not possible: no default task is set and "
155                        + "no task has been created with SynergyTaskManager." );
156                }
157                break;
158            case TASK_STATE_CREATED:
159                SynergyUtil.checkinTask( logger, currentTaskNumber, comment, ccmAddr );
160                currentTaskState = TASK_STATE_COMPLETED;
161                break;
162            case TASK_STATE_COMPLETED:
163                // if a default task is set, then check in that
164                // otherwise do nothing, as all tasks and all files with them have
165                // been checked in
166                if ( SynergyUtil.getDefaultTask( logger, ccmAddr ) != 0 )
167                {
168                    SynergyUtil.checkinDefaultTask( logger, comment, ccmAddr );
169                }
170                else
171                {
172                    if ( logger.isDebugEnabled() )
173                    {
174                        logger.debug( "Synergy : No check in necessary as default task and "
175                            + "all tasks created with SynergyTaskManager have already been checked in." );
176                    }
177                }
178                break;
179            default:
180                throw new IllegalStateException( "Programming error: SynergyTaskManager is in unkown state." );
181        }
182    }
183}