001    package org.apache.maven.scm.provider.integrity;
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 com.mks.api.Command;
023    import com.mks.api.FileOption;
024    import com.mks.api.Option;
025    import com.mks.api.response.APIException;
026    import com.mks.api.response.Response;
027    import com.mks.api.response.WorkItem;
028    
029    import java.io.File;
030    import java.util.Date;
031    
032    /**
033     * This class represents an Integrity SCM Member
034     * <br>It contains all the necessary metadata to check this file out individually
035     *
036     * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
037     * @version $Id: Member.java 1.2 2011/08/22 13:06:47EDT Cletus D'Souza (dsouza) Exp  $
038     * @since 1.6
039     */
040    public class Member
041    {
042        private String memberID;
043    
044        private String memberName;
045    
046        private Date memberTimestamp;
047    
048        private String memberDescription;
049    
050        private String projectConfigPath;
051    
052        private String memberRev;
053    
054        private File targetFile;
055    
056        private String relativeFile;
057    
058        private String lineTerminator;
059    
060        private String overwriteExisting;
061    
062        private String restoreTimestamp;
063    
064        /**
065         * This class represents an MKS Integrity Source File
066         * It needs the Member Name (relative path to pj), Full Member Path, Project Configuration Path, Revision,
067         * Project's Root Path, and the current Workspace directory (to compute the working file path) for its
068         * instantiation.  This helper class will be used to then perform a project checkout from the repository
069         *
070         * @param wi           A MKS API Response Work Item representing metadata related to a Integrity Member
071         * @param configPath   Configuration Path for this file's project/subproject
072         * @param projectRoot  Full path to the root location for this file's parent project
073         * @param workspaceDir Full path to the workspace root directory
074         */
075        public Member( WorkItem wi, String configPath, String projectRoot, String workspaceDir )
076        {
077            // Initialize our parent with the information needed
078            this.projectConfigPath = configPath;
079            this.memberID = wi.getId();
080            this.memberName = wi.getField( "name" ).getValueAsString();
081            this.memberRev = wi.getField( "memberrev" ).getItem().getId();
082            this.memberTimestamp = wi.getField( "membertimestamp" ).getDateTime();
083            if ( null != wi.getField( "memberdescription" ) && null != wi.getField(
084                "memberdescription" ).getValueAsString() )
085            {
086                this.memberDescription = wi.getField( "memberdescription" ).getValueAsString();
087            }
088            else
089            {
090                this.memberDescription = new String( "" );
091            }
092            this.lineTerminator = "native";
093            this.overwriteExisting = "overwriteExisting";
094            this.restoreTimestamp = "restoreTimestamp";
095            this.relativeFile = this.memberName.substring( projectRoot.length() );
096            this.targetFile = new File( workspaceDir + relativeFile );
097        }
098    
099        /**
100         * Returns a string representation of this file's full path name, where it will checked out to disk for the build.
101         *
102         * @return
103         */
104        public String getTargetFilePath()
105        {
106            return targetFile.getAbsolutePath();
107        }
108    
109        /**
110         * Returns a string representation of this member's revision
111         *
112         * @return
113         */
114        public String getRevision()
115        {
116            return memberRev;
117        }
118    
119        /**
120         * Returns the date/time associated with this member revision
121         *
122         * @return
123         */
124        public Date getTimestamp()
125        {
126            return memberTimestamp;
127        }
128    
129        /**
130         * Returns any check-in comments associated with this revision
131         *
132         * @return
133         */
134        public String getDescription()
135        {
136            return memberDescription;
137        }
138    
139        /**
140         * Returns the full server-side member path for this member
141         *
142         * @return
143         */
144        public String getMemberName()
145        {
146            return memberName;
147        }
148    
149        /**
150         * Returns only the file name portion for this full server-side member path
151         *
152         * @return
153         */
154        public String getName()
155        {
156            if ( memberID.indexOf( '/' ) > 0 )
157            {
158                return memberID.substring( memberID.lastIndexOf( '/' ) + 1 );
159            }
160            else if ( memberID.indexOf( '\\' ) > 0 )
161            {
162                return memberID.substring( memberID.lastIndexOf( '\\' ) + 1 );
163            }
164            else
165            {
166                return memberID;
167            }
168        }
169    
170        /**
171         * Optionally, one may set a line terminator, if the default is not desired.
172         *
173         * @param lineTerminator
174         */
175        public void setLineTerminator( String lineTerminator )
176        {
177            this.lineTerminator = lineTerminator;
178        }
179    
180        /**
181         * Optionally, one may choose not to overwrite existing files, this may speed up the synchronization process.
182         *
183         * @param overwriteExisting
184         */
185        public void setOverwriteExisting( String overwriteExisting )
186        {
187            this.overwriteExisting = overwriteExisting;
188        }
189    
190        /**
191         * Optionally, one might want to restore the timestamp, if the build is smart not to recompile files that were not touched.
192         *
193         * @param restoreTimestamp
194         */
195        public void setRestoreTimestamp( boolean restoreTime )
196        {
197            if ( restoreTime )
198            {
199                this.restoreTimestamp = "restoreTimestamp";
200            }
201            else
202            {
203                this.restoreTimestamp = "norestoreTimestamp";
204            }
205        }
206    
207        /**
208         * Performs a checkout of this MKS Integrity Source File to a working file location on the build server represented by targetFile
209         *
210         * @param api MKS API Session
211         * @return true if the operation succeeded or false if failed
212         * @throws APIException
213         */
214        public boolean checkout( APISession api )
215            throws APIException
216        {
217            // Make sure the directory is created
218            if ( !targetFile.getParentFile().isDirectory() )
219            {
220                targetFile.getParentFile().mkdirs();
221            }
222            // Construct the project check-co command
223            Command coCMD = new Command( Command.SI, "projectco" );
224            coCMD.addOption( new Option( overwriteExisting ) );
225            coCMD.addOption( new Option( "nolock" ) );
226            coCMD.addOption( new Option( "project", projectConfigPath ) );
227            coCMD.addOption( new FileOption( "targetFile", targetFile ) );
228            coCMD.addOption( new Option( restoreTimestamp ) );
229            coCMD.addOption( new Option( "lineTerminator", lineTerminator ) );
230            coCMD.addOption( new Option( "revision", memberRev ) );
231            // Add the member selection
232            coCMD.addSelection( memberID );
233    
234            // Execute the checkout command
235            Response res = api.runCommand( coCMD );
236    
237            // Return true if we were successful
238            if ( res.getExitCode() == 0 )
239            {
240                return true;
241            }
242            // Otherwise return false...
243            else
244            {
245                return false;
246            }
247        }
248    
249        /**
250         * Uses the name of file for equality check
251         */
252        @Override
253        public boolean equals( Object o )
254        {
255            if ( o instanceof Member )
256            {
257                if ( null != o )
258                {
259                    return ( (Member) o ).getMemberName().equals( this.getMemberName() );
260                }
261            }
262            return false;
263        }
264    }