
hudson.scm.IntegrityCMProject Maven / Gradle / Ivy
The newest version!
package hudson.scm;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.mks.api.Command;
import com.mks.api.Option;
import com.mks.api.response.APIException;
import com.mks.api.response.Response;
import com.mks.api.response.WorkItemIterator;
import com.mks.api.response.WorkItem;
import com.mks.api.response.Field;
import com.mks.api.si.SIModelTypeName;
/**
* This class represents an Integrity Configuration Management Project
* Provides metadata information about a SCM Project
*/
public class IntegrityCMProject implements Serializable
{
private static final long serialVersionUID = 6452315129657215760L;
public static final String NORMAL_PROJECT = "Normal";
public static final String VARIANT_PROJECT = "Variant";
public static final String BUILD_PROJECT = "Build";
private File projectDB;
private String projectName;
private String projectType;
private String projectRevision;
private String fullConfigSyntax;
private Date lastCheckpoint;
private String lineTerminator;
private boolean restoreTimestamp;
private boolean skipAuthorInfo;
private Document xmlDoc;
private StringBuffer changeLog;
private transient int changeCount;
/**
* Creates an instance of an Integrity CM Project
* and extracts all information from the API Response Field
* @param wi Work Item associated with the response from running si projectinfo
* @param projectDB Location of where the embedded derby database for this project
*/
public IntegrityCMProject(WorkItem wi, File projectDB)
{
// Initialize the project with default options
lineTerminator = "native";
restoreTimestamp = true;
skipAuthorInfo = false;
// Initialize the project's DB location
this.projectDB = projectDB;
// Initialize the change log report, if we need to compare with a baseline
changeLog = new StringBuffer();
changeCount = 0;
// Parse the current output from si projectinfo and cache the contents
initializeProject(wi);
}
public void initializeProject(WorkItem wi)
{
// Parse the current project information
try
{
// Get the metadata information about the project
Field pjNameFld = wi.getField("projectName");
Field pjTypeFld = wi.getField("projectType");
Field pjCfgPathFld = wi.getField("fullConfigSyntax");
Field pjChkptFld = wi.getField("lastCheckpoint");
// Convert to our class fields
// First obtain the project name field
if( null != pjNameFld && null != pjNameFld.getValueAsString() )
{
projectName = pjNameFld.getValueAsString();
}
else
{
Logger.warn("Project info did not provide a value for the 'projectName' field!");
projectName = "";
}
// Next, we'll need to know the project type
if( null != pjTypeFld && null != pjTypeFld.getValueAsString() )
{
projectType = pjTypeFld.getValueAsString();
if( isBuild() )
{
// Next, we'll need to know the current build checkpoint for this configuration
Field pjRevFld = wi.getField("revision");
if( null != pjRevFld && null != pjRevFld.getItem() )
{
projectRevision = pjRevFld.getItem().getId();
}
else
{
projectRevision = "";
Logger.warn("Project info did not provide a vale for the 'revision' field!");
}
}
}
else
{
Logger.warn("Project info did not provide a value for the 'projectType' field!");
projectType = "";
}
// Most important is the configuration path
if( null != pjCfgPathFld && null != pjCfgPathFld.getValueAsString() )
{
fullConfigSyntax = pjCfgPathFld.getValueAsString();
}
else
{
Logger.error("Project info did not provide a value for the 'fullConfigSyntax' field!");
fullConfigSyntax = "";
}
// Finally, we'll need to store the last checkpoint to figure out differences, etc.
if( null != pjChkptFld && null != pjChkptFld.getDateTime() )
{
lastCheckpoint = pjChkptFld.getDateTime();
}
else
{
Logger.warn("Project info did not provide a value for the 'lastCheckpoint' field!");
lastCheckpoint = Calendar.getInstance().getTime();
}
}
catch(NoSuchElementException nsee)
{
Logger.error("Project info did not provide a value for field " + nsee.getMessage());
}
}
/**
* Sets the optional line terminator option for this project
* @param lineTerminator
*/
public void setLineTerminator(String lineTerminator)
{
this.lineTerminator = lineTerminator;
}
/**
* Returns the line terminator setting for this project
* @return
*/
public String getLineTerminator()
{
return lineTerminator;
}
/**
* Sets the optional restore timestamp option for this project
* @param restoreTimestamp
*/
public void setRestoreTimestamp(boolean restoreTimestamp)
{
this.restoreTimestamp = restoreTimestamp;
}
/**
* Returns the restore timestamp setting for this project
* @return
*/
public boolean getRestoreTimestamp()
{
return restoreTimestamp;
}
/**
* Toggles whether or not to obtain the author using 'si revisioninfo'
* @param skipAuthorInfo
*/
public void setSkipAuthorInfo(boolean skipAuthorInfo)
{
this.skipAuthorInfo = skipAuthorInfo;
}
/**
* Opens a new connection to the embedded Integrity SCM Project cache db
* @return Connection to the embedded derby database
* @throws SQLException
*/
public Connection openProjectDB() throws SQLException
{
return DerbyUtils.createDBConnection(projectDB);
}
/**
* Closes the connections to the embedded derby database
*/
public void closeProjectDB()
{
DerbyUtils.shutdownDB(projectDB);
}
/**
* Parses the output from the si viewproject command to get a list of members
* @param wit WorkItemIterator
* @throws APIException
* @throws SQLException
*/
public void parseProject(WorkItemIterator wit) throws APIException, SQLException
{
// Setup the Derby DB for this Project
Connection db = openProjectDB();
PreparedStatement insert = null;
try
{
// Create a fresh set of tables for this project
DerbyUtils.createCMProjectTables(db);
// Initialize the project config hash
Hashtable pjConfigHash = new Hashtable();
// Add the mapping for the current project
pjConfigHash.put(this.projectName, this.fullConfigSyntax);
// Compute the project root directory
String projectRoot = projectName.substring(0, projectName.lastIndexOf('/'));
// Iterate through the list of members returned by the API
Logger.debug("Attempting to execute query " + DerbyUtils.INSERT_MEMBER_RECORD);
insert = db.prepareStatement(DerbyUtils.INSERT_MEMBER_RECORD);
while( wit.hasNext() )
{
WorkItem wi = wit.next();
if( wi.getModelType().equals(SIModelTypeName.SI_SUBPROJECT) )
{
// Save the configuration path for the current subproject, using the canonical path name
pjConfigHash.put(wi.getField("name").getValueAsString(), wi.getId());
// Save the relative directory path for this subproject
String pjDir = wi.getField("name").getValueAsString().substring(projectRoot.length());
pjDir = pjDir.substring(0, pjDir.lastIndexOf('/'));
// Save this directory entry
insert.clearParameters();
insert.setShort(1, (short)1); // Type
insert.setString(2, wi.getField("name").getValueAsString()); // Name
insert.setString(3, wi.getId()); // MemberID
insert.setTimestamp(4, new Timestamp(Calendar.getInstance().getTimeInMillis())); // Timestamp
insert.setClob(5, new StringReader("")); // Description
insert.setString(6, wi.getId()); // ConfigPath
insert.setString(7, ""); // Revision
insert.setString(8, pjDir); // RelativeFile
insert.executeUpdate();
}
else if( wi.getModelType().equals(SIModelTypeName.MEMBER) )
{
// Figure out this member's parent project's canonical path name
String parentProject = wi.getField("parent").getValueAsString();
// Save this member entry
String memberName = wi.getField("name").getValueAsString();
String description = "";
if( null != wi.getField("memberdescription") && null != wi.getField("memberdescription").getValueAsString() )
{
description = wi.getField("memberdescription").getValueAsString();
// Char 8211 which is a long dash causes problems for the change log XML, need to fix it!
description = description.replace((char)8211, '-');
}
insert.clearParameters();
insert.setShort(1, (short)0); // Type
insert.setString(2, memberName); // Name
insert.setString(3, wi.getId()); // MemberID
insert.setTimestamp(4, new Timestamp(wi.getField("membertimestamp").getDateTime().getTime())); // Timestamp
insert.setClob(5, new StringReader(description)); // Description
insert.setString(6, pjConfigHash.get(parentProject)); // ConfigPath
insert.setString(7, wi.getField("memberrev").getItem().getId()); // Revision
insert.setString(8, memberName.substring(projectRoot.length())); // RelativeFile
insert.executeUpdate();
}
else
{
Logger.warn("View project output contains an invalid model type: " + wi.getModelType());
}
}
// Commit to the database
db.commit();
}
finally
{
// Close the insert statement
if( null != insert ){ insert.close(); }
// Close the database connection
if( null != db ){ db.close(); }
}
// Log the completion of this operation
Logger.debug("Parsing project " + fullConfigSyntax + " complete!");
}
/**
* Updates the author information for all the members in the project
* @param api
* @throws SQLException
* @throws IOException
*/
public void primeAuthorInformation(APISession api) throws SQLException, IOException
{
Connection db = openProjectDB();
Statement authSelect = null;
ResultSet rs = null;
try
{
// Create the select statement for the current project
authSelect = db.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = authSelect.executeQuery(DerbyUtils.AUTHOR_SELECT);
while( rs.next() )
{
Hashtable rowHash = DerbyUtils.getRowData(rs);
rs.updateString(CM_PROJECT.AUTHOR.toString(),
IntegrityCMMember.getAuthor(api,
rowHash.get(CM_PROJECT.CONFIG_PATH).toString(),
rowHash.get(CM_PROJECT.MEMBER_ID).toString(),
rowHash.get(CM_PROJECT.REVISION).toString()));
rs.updateRow();
}
// Commit the updates
db.commit();
}
finally
{
// Release the result set
if( null != rs ){ rs.close(); }
// Release the statement
if( null != authSelect ){ authSelect.close(); }
// Close project db connections
if( null != db ){ db.close(); }
}
}
/**
* Updates the underlying Integrity SCM Project table cache with the new checksum information
* @param checksumHash Checksum hashtable generated from a checkout operation
* @throws SQLException
* @throws IOException
*/
public void updateChecksum(Hashtable checksumHash) throws SQLException, IOException
{
Connection db = openProjectDB();
Statement checksumSelect = null;
ResultSet rs = null;
try
{
// Create the select statement for the current project
checksumSelect = db.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = checksumSelect.executeQuery(DerbyUtils.CHECKSUM_UPDATE);
while( rs.next() )
{
Hashtable rowHash = DerbyUtils.getRowData(rs);
String newChecksum = checksumHash.get(rowHash.get(CM_PROJECT.NAME).toString());
if( null != newChecksum && newChecksum.length() > 0 )
{
rs.updateString(CM_PROJECT.CHECKSUM.toString(), newChecksum);
rs.updateRow();
}
}
// Commit the updates
db.commit();
}
finally
{
// Release the result set
if( null != rs ){ rs.close(); }
// Release the statement
if( null != checksumSelect ){ checksumSelect.close(); }
// Close project db connections
if( null != db ){ db.close(); }
}
}
/**
* Compares this version of the project to a previous/new version to determine what are the updates and what was deleted
* @param baselineProjectDB The previous baseline (build) for this Integrity CM Project
* @param api The current Integrity API Session to obtain the author information
* @param return The total number of changes found in the comparison
* @throws SQLException
* @throws IOException
*/
public int compareBaseline(File baselineProjectDB, APISession api) throws SQLException, IOException
{
// Re-initialize our return variable
changeCount = 0;
// Open connections to the embedded Integrity SCM Project cache databases
Connection baselineDB = DerbyUtils.createDBConnection(baselineProjectDB);
Connection db = openProjectDB();
Statement baselineSelect = null;
Statement pjSelect = null;
ResultSet baselineRS = null;
ResultSet rs = null;
try
{
// Create the select statement for the previous baseline
baselineSelect = baselineDB.createStatement();
Logger.debug("Attempting to execute query " + DerbyUtils.BASELINE_SELECT);
baselineRS = baselineSelect.executeQuery(DerbyUtils.BASELINE_SELECT);
// Create a hashtable to hold the old baseline for easy comparison
Hashtable> baselinePJ = new Hashtable>();
while( baselineRS.next() )
{
Hashtable rowHash = DerbyUtils.getRowData(baselineRS);
Hashtable memberInfo = new Hashtable();
memberInfo.put(CM_PROJECT.MEMBER_ID, (null == rowHash.get(CM_PROJECT.MEMBER_ID) ? "" : rowHash.get(CM_PROJECT.MEMBER_ID).toString()));
memberInfo.put(CM_PROJECT.TIMESTAMP, (null == rowHash.get(CM_PROJECT.TIMESTAMP) ? "" : (Date)rowHash.get(CM_PROJECT.TIMESTAMP)));
memberInfo.put(CM_PROJECT.DESCRIPTION, (null == rowHash.get(CM_PROJECT.DESCRIPTION) ? "" : rowHash.get(CM_PROJECT.DESCRIPTION).toString()));
memberInfo.put(CM_PROJECT.AUTHOR, (null == rowHash.get(CM_PROJECT.AUTHOR) ? "" : rowHash.get(CM_PROJECT.AUTHOR).toString()));
memberInfo.put(CM_PROJECT.CONFIG_PATH, (null == rowHash.get(CM_PROJECT.CONFIG_PATH) ? "" : rowHash.get(CM_PROJECT.CONFIG_PATH).toString()));
memberInfo.put(CM_PROJECT.REVISION, (null == rowHash.get(CM_PROJECT.REVISION) ? "" : rowHash.get(CM_PROJECT.REVISION).toString()));
memberInfo.put(CM_PROJECT.RELATIVE_FILE, (null == rowHash.get(CM_PROJECT.RELATIVE_FILE) ? "" : rowHash.get(CM_PROJECT.RELATIVE_FILE).toString()));
memberInfo.put(CM_PROJECT.CHECKSUM, (null == rowHash.get(CM_PROJECT.CHECKSUM) ? "" : rowHash.get(CM_PROJECT.CHECKSUM).toString()));
baselinePJ.put(rowHash.get(CM_PROJECT.NAME).toString(), memberInfo);
}
// Create the select statement for the current project
pjSelect = db.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
Logger.debug("Attempting to execute query " + DerbyUtils.DELTA_SELECT);
rs = pjSelect.executeQuery(DerbyUtils.DELTA_SELECT);
// Now we will compare the adds and updates between the current project and the baseline
for( int i = 1; i <= DerbyUtils.getRowCount(rs); i++ )
{
// Move the cursor to the current record
rs.absolute(i);
Hashtable rowHash = DerbyUtils.getRowData(rs);
// Obtain the member we're working with
String memberName = rowHash.get(CM_PROJECT.NAME).toString();
// Get the baseline project information for this member
Logger.debug("Comparing file against baseline " + memberName);
Hashtable baselineMemberInfo = baselinePJ.get(memberName);
// This file was in the previous baseline as well...
if( null != baselineMemberInfo )
{
// Did it change? Either by an update or roll back (update member revision)?
String oldRevision = baselineMemberInfo.get(CM_PROJECT.REVISION).toString();
if( ! rowHash.get(CM_PROJECT.REVISION).toString().equals(oldRevision) )
{
// Initialize the prior revision
rs.updateString(CM_PROJECT.OLD_REVISION.toString(), oldRevision);
// Initialize the author information as requested
if( ! skipAuthorInfo ){ rs.updateString(CM_PROJECT.AUTHOR.toString(),
IntegrityCMMember.getAuthor(api,
rowHash.get(CM_PROJECT.CONFIG_PATH).toString(),
rowHash.get(CM_PROJECT.MEMBER_ID).toString(),
rowHash.get(CM_PROJECT.REVISION).toString())); }
// Initialize the delta flag for this member
rs.updateShort(CM_PROJECT.DELTA.toString(), (short)2);
changeCount++;
}
else
{
// This member did not change, so lets copy its old author information
if( null != baselineMemberInfo.get(CM_PROJECT.AUTHOR) )
{
rs.updateString(CM_PROJECT.AUTHOR.toString(), baselineMemberInfo.get(CM_PROJECT.AUTHOR).toString());
}
// Also, lets copy over the previous MD5 checksum
if( null != baselineMemberInfo.get(CM_PROJECT.CHECKSUM) )
{
rs.updateString(CM_PROJECT.CHECKSUM.toString(), baselineMemberInfo.get(CM_PROJECT.CHECKSUM).toString());
}
// Initialize the delta flag
rs.updateShort(CM_PROJECT.DELTA.toString(), (short)0);
}
// Remove this member from the baseline project hashtable, so we'll be left with items that are dropped
baselinePJ.remove(memberName);
}
else // We've found a new file
{
// Initialize the author information as requested
if( ! skipAuthorInfo ){ rs.updateString(CM_PROJECT.AUTHOR.toString(),
IntegrityCMMember.getAuthor(api,
rowHash.get(CM_PROJECT.CONFIG_PATH).toString(),
rowHash.get(CM_PROJECT.MEMBER_ID).toString(),
rowHash.get(CM_PROJECT.REVISION).toString())); }
// Initialize the delta flag for this member
rs.updateShort(CM_PROJECT.DELTA.toString(), (short)1);
changeCount++;
}
// Update this row in the data source
rs.updateRow();
}
// Now, we should be left with the drops. Exist only in the old baseline and not the current one.
Enumeration deletedMembers = baselinePJ.keys();
while( deletedMembers.hasMoreElements() )
{
changeCount++;
String memberName = deletedMembers.nextElement();
Hashtable memberInfo = baselinePJ.get(memberName);
// Add the deleted members to the database
rs.moveToInsertRow();
rs.updateShort(CM_PROJECT.TYPE.toString(), (short)0);
rs.updateString(CM_PROJECT.NAME.toString(), memberName);
rs.updateString(CM_PROJECT.MEMBER_ID.toString(), memberInfo.get(CM_PROJECT.MEMBER_ID).toString());
if( memberInfo.get(CM_PROJECT.TIMESTAMP) instanceof java.util.Date )
{
Timestamp ts = new Timestamp(((Date)memberInfo.get(CM_PROJECT.TIMESTAMP)).getTime());
rs.updateTimestamp(CM_PROJECT.TIMESTAMP.toString(), ts);
}
rs.updateString(CM_PROJECT.DESCRIPTION.toString(), memberInfo.get(CM_PROJECT.DESCRIPTION).toString());
rs.updateString(CM_PROJECT.AUTHOR.toString(), memberInfo.get(CM_PROJECT.AUTHOR).toString());
rs.updateString(CM_PROJECT.CONFIG_PATH.toString(), memberInfo.get(CM_PROJECT.CONFIG_PATH).toString());
rs.updateString(CM_PROJECT.REVISION.toString(), memberInfo.get(CM_PROJECT.REVISION).toString());
rs.updateString(CM_PROJECT.RELATIVE_FILE.toString(), memberInfo.get(CM_PROJECT.RELATIVE_FILE).toString());
rs.updateShort(CM_PROJECT.DELTA.toString(), (short)3);
rs.insertRow();
rs.moveToCurrentRow();
}
// Commit changes to the database...
db.commit();
}
finally
{
// Close the result set and select statements
if( null != baselineRS ){ baselineRS.close(); }
if( null != rs ){ rs.close(); }
if( null != baselineSelect ){ baselineSelect.close(); }
if( null != pjSelect ){ pjSelect.close(); }
// Close DB connections
if( null != baselineDB ){ baselineDB.close(); }
if( null != db ){ db.close(); }
// Shutdown the baseline project DB
DerbyUtils.shutdownDB(baselineProjectDB);
}
return changeCount;
}
/**
* Project access function that returns the state of the current project
* NOTE: For maximum efficiency, this should be called only once and after the compareBasline() has been invoked!
* @return A List containing every member in this project, including any dropped artifacts
* @throws SQLException
* @throws IOException
*/
public List> viewProject() throws SQLException, IOException
{
// Initialize our return variable
List> projectMembersList = new ArrayList>();
// Initialize our db connection
Connection db = openProjectDB();
Statement stmt = null;
ResultSet rs = null;
try
{
stmt = db.createStatement();
rs = stmt.executeQuery(DerbyUtils.PROJECT_SELECT);
while( rs.next() )
{
projectMembersList.add(DerbyUtils.getRowData(rs));
}
}
finally
{
// Close the database resources
if( null != rs ){ rs.close(); }
if( null != stmt ){ stmt.close(); }
if( null != db ){ db.close(); }
}
return projectMembersList;
}
/**
* Returns the Change Log based on the project baseline comparison
* This assumes that compareBaseline() has been called already
* @return
* @throws DOMException
*/
public String getChangeLog(String version, List> projectMembersList) throws DOMException
{
try
{
// Initialize the XML document builder
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// Initialize the XML Document and change log
xmlDoc = docBuilder.newDocument();
changeLog = new StringBuffer();
// Create the root element
Element changeLogElem = xmlDoc.createElement("changelog");
// Add the to the xmlDoc
xmlDoc.appendChild(changeLogElem);
// Add the change log details, if the project has changed
if( changeCount > 0 )
{
// Create the element
Element items = xmlDoc.createElement("items");
// Set the version attribute to the element
items.setAttribute("version", version);
// Append the to the root element
changeLogElem.appendChild(items);
// Process the changes...
for( Iterator> it = projectMembersList.iterator(); it.hasNext(); )
{
Hashtable memberInfo = it.next();
short deltaFlag = Short.valueOf(memberInfo.get(CM_PROJECT.DELTA).toString());
if( deltaFlag > 0 )
{
// Create the individual - element for the add/update/drop
Element item = xmlDoc.createElement("item");
// Set the action attribute
if( deltaFlag == 1 ){ item.setAttribute("action", "add"); }
else if( deltaFlag == 2 ){ item.setAttribute("action", "update"); }
else if( deltaFlag == 3 ){ item.setAttribute("action", "delete"); }
else{ item.setAttribute("action", "undefined"); }
// Append the
- to the
element
items.appendChild(writeChangeLog(item, memberInfo));
}
}
}
// Write the content into a String
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer serializer = tfactory.newTransformer();
// Setup indenting for a readable output
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
StringWriter sw = new StringWriter();
serializer.transform(new DOMSource(xmlDoc), new StreamResult(sw));
changeLog.append(sw.toString());
sw.close();
}
catch(ParserConfigurationException pce)
{
Logger.warn("Caught Parser Configuration Exception while generating Change Log!");
Logger.warn(pce.getMessage());
}
catch(TransformerException tfe)
{
Logger.warn("Caught Transformer Exception while generating Change Log!");
Logger.warn(tfe.getMessage());
}
catch(IOException ioe)
{
Logger.warn("Caught IO Exception while generating Change Log!");
Logger.warn(ioe.getMessage());
}
return changeLog.toString();
}
/**
* Helper function to append details to the Change Log for each member
* Convenience method to wrap the details around adds, updates, and deletes
* @param item XML Element representing the item node
* @param memberInfo Hashtable representing the member information
*/
private Element writeChangeLog(Element item, Hashtable memberInfo)
{
// Create and append the element
Element file = xmlDoc.createElement("file");
file.appendChild(xmlDoc.createTextNode(memberInfo.get(CM_PROJECT.NAME).toString()));
item.appendChild(file);
// Create and append the element
Element user = xmlDoc.createElement("user");
user.appendChild(xmlDoc.createTextNode(memberInfo.get(CM_PROJECT.AUTHOR).toString()));
item.appendChild(user);
// Create and append the element
Element revision = xmlDoc.createElement("rev");
revision.appendChild(xmlDoc.createTextNode(memberInfo.get(CM_PROJECT.REVISION).toString()));
item.appendChild(revision);
// Create and append the element
Element date = xmlDoc.createElement("date");
date.appendChild(xmlDoc.createTextNode(IntegritySCM.SDF.format((Timestamp)memberInfo.get(CM_PROJECT.TIMESTAMP))));
item.appendChild(date);
// Create and append the annotation and differences links
try
{
// Add the element
Element annotation = xmlDoc.createElement("annotation");
annotation.appendChild(xmlDoc.createCDATASection(IntegrityCMMember.getAnnotatedLink(
memberInfo.get(CM_PROJECT.CONFIG_PATH).toString(),
memberInfo.get(CM_PROJECT.MEMBER_ID).toString(),
memberInfo.get(CM_PROJECT.REVISION).toString())));
item.appendChild(annotation);
// Add the element
Element differences = xmlDoc.createElement("differences");
String oldRev = (null != memberInfo.get(CM_PROJECT.OLD_REVISION) ? memberInfo.get(CM_PROJECT.OLD_REVISION).toString() : "");
differences.appendChild(xmlDoc.createCDATASection(oldRev.length() > 0 ?
IntegrityCMMember.getDifferencesLink(
memberInfo.get(CM_PROJECT.CONFIG_PATH).toString(),
memberInfo.get(CM_PROJECT.MEMBER_ID).toString(),
memberInfo.get(CM_PROJECT.REVISION).toString(), oldRev) : ""));
item.appendChild(differences);
}
catch(UnsupportedEncodingException uee)
{
Logger.warn("Caught Unsupported Encoding Exception while generating Integrity Source links!");
Logger.warn(uee.getMessage());
}
// Finally, create and append the element
Element msg = xmlDoc.createElement("msg");
msg.appendChild(xmlDoc.createCDATASection(memberInfo.get(CM_PROJECT.DESCRIPTION).toString()));
item.appendChild(msg);
// Return the updated - element
return item;
}
/**
* Performs a checkpoint on this Integrity CM Project
* @param api Authenticated Integrity API Session
* @param chkptLabel Checkpoint label string
* @return Integrity API Response object
* @throws APIException
*/
public Response checkpoint(APISession api, String chkptLabel) throws APIException
{
// Construct the checkpoint command
Command siCheckpoint = new Command(Command.SI, "checkpoint");
// Set the project name
siCheckpoint.addOption(new Option("project", fullConfigSyntax));
// Set the label and description if applicable
if( null != chkptLabel && chkptLabel.length() > 0 )
{
// Set the label
siCheckpoint.addOption(new Option("label", chkptLabel));
// Set the description
siCheckpoint.addOption(new Option("description", chkptLabel));
}
return api.runCommand(siCheckpoint);
}
/**
* Applies a Project Label on this Integrity CM Project
* @param api Authenticated Integrity API Session
* @param chkptLabel Checkpoint label string
* @return Integrity API Response object
* @throws APIException
*/
public Response addProjectLabel(APISession api, String chkptLabel) throws APIException
{
// Construct the addprojectlabel command
Command siAddProjectLabel = new Command(Command.SI, "addprojectlabel");
// Set the project name
siAddProjectLabel.addOption(new Option("project", fullConfigSyntax));
// Set the label
siAddProjectLabel.addOption(new Option("label", chkptLabel));
// Move the label, if a previous one was applied
siAddProjectLabel.addOption(new Option("moveLabel"));
return api.runCommand(siAddProjectLabel);
}
/**
* Returns a string list of relative paths to all directories in this project
* @return
* @throws SQLException
* @throws IOException
*/
public List
getDirList() throws SQLException, IOException
{
// Initialize our return variable
List dirList = new ArrayList();
// Initialize our db connection
Connection db = openProjectDB();
Statement stmt = null;
ResultSet rs = null;
try
{
stmt = db.createStatement();
rs = stmt.executeQuery(DerbyUtils.DIR_SELECT);
while( rs.next() )
{
Hashtable rowData = DerbyUtils.getRowData(rs);
dirList.add(rowData.get(CM_PROJECT.RELATIVE_FILE).toString());
}
}
finally
{
// Close the database resources
if( null != rs ){ rs.close(); }
if( null != stmt ){ stmt.close(); }
if( null != db ){ db.close(); }
}
return dirList;
}
/**
* Returns the project path for this Integrity CM Project
* @return
*/
public String getProjectName()
{
return projectName;
}
/**
* Returns the project revision for this Integrity SCM Project
* @return
*/
public String getProjectRevision()
{
return projectRevision;
}
/**
* Returns true is this is a Normal Project
* @return
*/
public boolean isNormal()
{
if( projectType.equalsIgnoreCase(NORMAL_PROJECT) )
{
return true;
}
else
{
return false;
}
}
/**
* Returns true if this is a Variant Project
* @return
*/
public boolean isVariant()
{
if( projectType.equalsIgnoreCase(VARIANT_PROJECT) )
{
return true;
}
else
{
return false;
}
}
/**
* Returns true if this is a Build Project
* @return
*/
public boolean isBuild()
{
if( projectType.equalsIgnoreCase(BUILD_PROJECT) )
{
return true;
}
else
{
return false;
}
}
/**
* Returns the Full Configuration Path for this Integrity CM Project
* @return
*/
public String getConfigurationPath()
{
return fullConfigSyntax;
}
/**
* Returns the date when the last checkpoint was performed on this Project
* @return
*/
public Date getLastCheckpointDate()
{
return lastCheckpoint;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy