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