001    package 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    
022    import org.apache.maven.scm.ScmException;
023    import org.apache.maven.scm.ScmFile;
024    import org.apache.maven.scm.ScmFileSet;
025    import org.apache.maven.scm.ScmFileStatus;
026    import org.apache.maven.scm.ScmVersion;
027    import org.apache.maven.scm.command.changelog.ChangeLogCommand;
028    import org.apache.maven.scm.command.update.AbstractUpdateCommand;
029    import org.apache.maven.scm.command.update.UpdateScmResult;
030    import org.apache.maven.scm.provider.ScmProviderRepository;
031    import org.apache.maven.scm.provider.synergy.command.SynergyCommand;
032    import org.apache.maven.scm.provider.synergy.command.changelog.SynergyChangeLogCommand;
033    import org.apache.maven.scm.provider.synergy.repository.SynergyScmProviderRepository;
034    import org.apache.maven.scm.provider.synergy.util.SynergyUtil;
035    import org.codehaus.plexus.util.FileUtils;
036    
037    import java.io.File;
038    import java.io.IOException;
039    import java.util.ArrayList;
040    import java.util.List;
041    
042    /**
043     * @author <a href="mailto:julien.henry@capgemini.com">Julien Henry</a>
044     * @version $Id: SynergyUpdateCommand.java 1333668 2012-05-03 22:37:08Z hboutemy $
045     */
046    public 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, List<ScmFile> modifications )
130            throws IOException
131        {
132            if ( !sourceDirectory.exists() )
133            {
134                throw new IOException( "Source directory doesn't exists (" + sourceDirectory.getAbsolutePath() + ")." );
135            }
136    
137            File[] files = sourceDirectory.listFiles();
138    
139            String sourcePath = sourceDirectory.getAbsolutePath();
140    
141            for ( File file : files )
142            {
143                String dest = file.getAbsolutePath();
144    
145                dest = dest.substring( sourcePath.length() + 1 );
146    
147                File destination = new File( destinationDirectory, dest );
148    
149                if ( file.isFile() )
150                {
151    
152                    if ( file.lastModified() != destination.lastModified() )
153                    {
154    
155                        destination = destination.getParentFile();
156    
157                        FileUtils.copyFileToDirectory( file, destination );
158    
159                        modifications.add( new ScmFile( file.getAbsolutePath(), ScmFileStatus.UPDATED ) );
160    
161                    }
162                }
163                else if ( file.isDirectory() )
164                {
165                    if ( !destination.exists() && !destination.mkdirs() )
166                    {
167                        throw new IOException(
168                            "Could not create destination directory '" + destination.getAbsolutePath() + "'." );
169                    }
170    
171                    copyDirectoryStructure( file, destination, modifications );
172                }
173                else
174                {
175                    throw new IOException( "Unknown file type: " + file.getAbsolutePath() );
176                }
177            }
178        }
179    
180    }