001package org.apache.maven.scm.provider.synergy.command.update;
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.ScmFile;
024import org.apache.maven.scm.ScmFileSet;
025import org.apache.maven.scm.ScmFileStatus;
026import org.apache.maven.scm.ScmVersion;
027import org.apache.maven.scm.command.changelog.ChangeLogCommand;
028import org.apache.maven.scm.command.update.AbstractUpdateCommand;
029import org.apache.maven.scm.command.update.UpdateScmResult;
030import org.apache.maven.scm.provider.ScmProviderRepository;
031import org.apache.maven.scm.provider.synergy.command.SynergyCommand;
032import org.apache.maven.scm.provider.synergy.command.changelog.SynergyChangeLogCommand;
033import org.apache.maven.scm.provider.synergy.repository.SynergyScmProviderRepository;
034import org.apache.maven.scm.provider.synergy.util.SynergyUtil;
035import org.codehaus.plexus.util.FileUtils;
036
037import java.io.File;
038import java.io.IOException;
039import java.util.ArrayList;
040import java.util.List;
041
042/**
043 * @author <a href="mailto:julien.henry@capgemini.com">Julien Henry</a>
044 *
045 */
046public class SynergyUpdateCommand
047    extends AbstractUpdateCommand
048    implements SynergyCommand
049{
050    /** {@inheritDoc} */
051    protected UpdateScmResult executeUpdateCommand( ScmProviderRepository repository, ScmFileSet fileSet,
052                                                    ScmVersion version )
053        throws ScmException
054    {
055        if ( getLogger().isDebugEnabled() )
056        {
057            getLogger().debug( "executing update command..." );
058        }
059        SynergyScmProviderRepository repo = (SynergyScmProviderRepository) repository;
060
061        if ( getLogger().isDebugEnabled() )
062        {
063            getLogger().debug( "basedir: " + fileSet.getBasedir() );
064        }
065
066        String ccmAddr = SynergyUtil.start( getLogger(), repo.getUser(), repo.getPassword(), null );
067
068        File waPath;
069        try
070        {
071            String projectSpec =
072                SynergyUtil.getWorkingProject( getLogger(), repo.getProjectSpec(), repo.getUser(), ccmAddr );
073            SynergyUtil.reconfigureProperties( getLogger(), projectSpec, ccmAddr );
074            SynergyUtil.reconfigure( getLogger(), projectSpec, ccmAddr );
075            // We need to get WA path
076            waPath = SynergyUtil.getWorkArea( getLogger(), projectSpec, ccmAddr );
077        }
078        finally
079        {
080            SynergyUtil.stop( getLogger(), ccmAddr );
081        }
082
083        File source = new File( waPath, repo.getProjectName() );
084
085        // Move file from work area to expected dir if not the same
086        List<ScmFile> modifications = new ArrayList<ScmFile>();
087        if ( !source.equals( fileSet.getBasedir() ) )
088        {
089            if ( getLogger().isInfoEnabled() )
090            {
091                getLogger().info( "We will copy modified files from Synergy Work Area [" + source
092                                  + "] to expected folder [" + fileSet.getBasedir() + "]" );
093            }
094            try
095            {
096                copyDirectoryStructure( source, fileSet.getBasedir(), modifications );
097            }
098            catch ( IOException e1 )
099            {
100                throw new ScmException( "Unable to copy directory structure", e1 );
101            }
102        }
103
104        return new UpdateScmResult( "ccm reconcile -uwa ...", modifications );
105    }
106
107    protected ChangeLogCommand getChangeLogCommand()
108    {
109        SynergyChangeLogCommand changeLogCmd = new SynergyChangeLogCommand();
110
111        changeLogCmd.setLogger( getLogger() );
112
113        return changeLogCmd;
114    }
115
116    /**
117     * Copies a entire directory structure and collect modifications.
118     * <p/>
119     * Note:
120     * <ul>
121     * <li>It will include empty directories.
122     * <li>The <code>sourceDirectory</code> must exists.
123     * </ul>
124     *
125     * @param sourceDirectory
126     * @param destinationDirectory
127     * @throws IOException
128     */
129    public static void copyDirectoryStructure( File sourceDirectory, File destinationDirectory,
130                                               List<ScmFile> modifications )
131        throws IOException
132    {
133        if ( !sourceDirectory.exists() )
134        {
135            throw new IOException( "Source directory doesn't exists (" + sourceDirectory.getAbsolutePath() + ")." );
136        }
137
138        File[] files = sourceDirectory.listFiles();
139
140        String sourcePath = sourceDirectory.getAbsolutePath();
141
142        for ( File file : files )
143        {
144            String dest = file.getAbsolutePath();
145
146            dest = dest.substring( sourcePath.length() + 1 );
147
148            File destination = new File( destinationDirectory, dest );
149
150            if ( file.isFile() )
151            {
152
153                if ( file.lastModified() != destination.lastModified() )
154                {
155
156                    destination = destination.getParentFile();
157
158                    FileUtils.copyFileToDirectory( file, destination );
159
160                    modifications.add( new ScmFile( file.getAbsolutePath(), ScmFileStatus.UPDATED ) );
161
162                }
163            }
164            else if ( file.isDirectory() )
165            {
166                if ( !destination.exists() && !destination.mkdirs() )
167                {
168                    throw new IOException(
169                        "Could not create destination directory '" + destination.getAbsolutePath() + "'." );
170                }
171
172                copyDirectoryStructure( file, destination, modifications );
173            }
174            else
175            {
176                throw new IOException( "Unknown file type: " + file.getAbsolutePath() );
177            }
178        }
179    }
180
181}