/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.netbeans.lib.cvsclient.command.log;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.netbeans.lib.cvsclient.command.FileInfoContainer;
import org.netbeans.lib.cvsclient.util.BugLog;
/**
* Describes log information for a file. This is the result of doing a cvs log command. The fields in instances of this object are populated
* by response handlers.
*
* @author Milos Kleint
*/
public class LogInformation extends FileInfoContainer {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); // NOI18N
private File file;
private String repositoryFilename;
private String headRevision;
private String branch;
private String accessList;
private String keywordSubstitution;
private String totalRevisions;
private String selectedRevisions;
private String description;
private String locks;
private final List revisions = new ArrayList();
private final List symbolicNames = new ArrayList();
public LogInformation() {
}
/**
* Getter for property file.
*
* @return Value of property file.
*/
@Override
public File getFile() {
return file;
}
/**
* Setter for property file.
*
* @param file
* New value of property file.
*/
public void setFile(File file) {
this.file = file;
}
/**
* Getter for property repositoryFilename.
*
* @return Value of property repositoryFilename.
*/
public String getRepositoryFilename() {
return repositoryFilename;
}
/**
* Setter for property repositoryFilename.
*
* @param repositoryFilename
* New value of property repositoryFilename.
*/
public void setRepositoryFilename(String repositoryFilename) {
this.repositoryFilename = repositoryFilename;
}
/**
* Getter for property headRevision.
*
* @return Value of property headRevision.
*/
public String getHeadRevision() {
return headRevision;
}
/**
* Setter for property headRevision.
*
* @param headRevision
* New value of property headRevision.
*/
public void setHeadRevision(String headRevision) {
this.headRevision = headRevision;
}
/**
* Getter for property branch.
*
* @return Value of property branch.
*/
public String getBranch() {
return branch;
}
/**
* Setter for property branch.
*
* @param branch
* New value of property branch.
*/
public void setBranch(String branch) {
this.branch = branch;
}
/**
* Getter for property accessList.
*
* @return Value of property accessList.
*/
public String getAccessList() {
return accessList;
}
/**
* Setter for property accessList.
*
* @param accessList
* New value of property accessList.
*/
public void setAccessList(String accessList) {
this.accessList = accessList;
}
/**
* Getter for property keywordSubstitution.
*
* @return Value of property keywordSubstitution.
*/
public String getKeywordSubstitution() {
return keywordSubstitution;
}
/**
* Setter for property keywordSubstitution.
*
* @param keywordSubstitution
* New value of property keywordSubstitution.
*/
public void setKeywordSubstitution(String keywordSubstitution) {
this.keywordSubstitution = keywordSubstitution;
}
/**
* Getter for property totalRevisions.
*
* @return Value of property totalRevisions.
*/
public String getTotalRevisions() {
return totalRevisions;
}
/**
* Setter for property totalRevisions.
*
* @param totalRevisions
* New value of property totalRevisions.
*/
public void setTotalRevisions(String totalRevisions) {
this.totalRevisions = totalRevisions;
}
/**
* Getter for property selectedRevisions.
*
* @return Value of property selectedRevisions.
*/
public String getSelectedRevisions() {
return selectedRevisions;
}
/**
* Setter for property selectedRevisions.
*
* @param selectedRevisions
* New value of property selectedRevisions.
*/
public void setSelectedRevisions(String selectedRevisions) {
this.selectedRevisions = selectedRevisions;
}
/**
* Getter for property description.
*
* @return Value of property description.
*/
public String getDescription() {
return description;
}
/**
* Setter for property description.
*
* @param description
* New value of property description.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Getter for property locks.
*
* @return Value of property locks.
*/
public String getLocks() {
return locks;
}
/**
* Setter for property locks.
*
* @param locks
* New value of property locks.
*/
public void setLocks(String locks) {
this.locks = locks;
}
/**
* adds a revision info to the LogInformation instance
*/
public void addRevision(LogInformation.Revision newRevision) {
revisions.add(newRevision);
}
/**
* return the all revisions attached to this log (if more sophisticated method are supplied, this might get obsolete)
*/
public List getRevisionList() {
return revisions;
}
/**
* Search the revisions by number of revision. If not found, return null.
*/
public LogInformation.Revision getRevision(String number) {
Iterator it = revisions.iterator();
LogInformation.Revision item;
while (it.hasNext()) {
item = (LogInformation.Revision) it.next();
if (item.getNumber().equals(number)) {
return item;
}
}
return null;
}
/**
* Add a symbolic name to the list of names and attaches it to a revision number.
*/
public void addSymbolicName(String symName, String revisionNumber) {
SymName newName = new SymName();
newName.setName(symName);
newName.setRevision(revisionNumber);
symbolicNames.add(newName);
}
public List getAllSymbolicNames() {
return symbolicNames;
}
/**
* Search the symbolic names by number of revision. If not found, return null.
*/
public List getSymNamesForRevision(String revNumber) {
Iterator it = symbolicNames.iterator();
LogInformation.SymName item;
List list = new LinkedList();
while (it.hasNext()) {
item = (LogInformation.SymName) it.next();
if (item.getRevision().equals(revNumber)) {
list.add(item);
}
}
return list;
}
/**
* Search the symbolic names by name of tag (symbolic name). If not found, return null.
*/
public LogInformation.SymName getSymName(String symName) {
Iterator it = symbolicNames.iterator();
LogInformation.SymName item;
while (it.hasNext()) {
item = (LogInformation.SymName) it.next();
if (item.getName().equals(symName)) {
return item;
}
}
return null;
}
public Revision createNewRevision(String number) {
Revision rev = new Revision();
rev.setNumber(number);
return rev;
}
/**
* Return a string representation of this object. Useful for debugging.
*/
@Override
public String toString() {
StringBuffer buf = new StringBuffer(30);
buf.append("\nFile: " + (file != null ? file.getAbsolutePath() : "null")); // NOI18N
buf.append("\nRepositoryFile: " + repositoryFilename); // NOI18N
buf.append("\nHead revision: " + headRevision); // NOI18N
return buf.toString();
}
public class SymName {
private String name;
private String revision;
public SymName() {
}
public String getName() {
return name;
}
public void setName(String symName) {
name = symName;
}
public void setRevision(String rev) {
revision = rev;
}
public String getRevision() {
return revision;
}
/**
* Determines if given name represents a branch tag test is based on revision num parsing and looking for trailing <tt>0.#</tt>
* (1.1.0.2, 1.2.4.5.0.6, ,..).
*/
public final boolean isBranch() {
boolean branch = false;
String[] nums = revision.split("\\.");
if (nums.length > 2 && nums.length % 2 == 0) {
String lastButOne = nums[nums.length - 2];
branch = "0".equals(lastButOne); // NOI18N
}
return branch;
}
}
public class Revision {
/**
* The revision number.
*/
private String number;
/**
* The parsed date.
*/
private Date date;
/**
* The String representation of the date.
*/
private String dateString;
/**
* The author of the revision.
*/
private String author;
/**
* The state.
*/
private String state;
/**
* The added/removed lines.
*/
private String lines;
/**
* The commit ID, as generated and reported by some servers.
*/
private String commitID;
/**
* The commit log-message.
*/
private String message;
/**
* The branches for this revision.
*/
private String branches;
public Revision() {
/**
* Since these have to be initialized when correctly parsing the command's output, then initializing them to empty strings is a
* safety measure against bad parsing errors. what about backward compatibility here??
*
* state = ""; lines = ""; message = ""; branches = "";
*/
}
public LogInformation getLogInfoHeader() {
return LogInformation.this;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getDate() {
return date;
}
public String getDateString() {
return dateString;
}
/**
* @deprecated This method uses a static parser to parse dates which is not thread safe, use #setDate instead
*/
@Deprecated
public void setDateString(String dateString) {
this.dateString = dateString;
if (dateString == null) {
this.date = null;
return;
}
// Parse the date ...
try {
// some servers use dashes to separate date components, so replace with slashes
// also add a default GMT timezone at the end, if the server already put one in this one will be ignored by the parser
dateString = dateString.replace('/', '-') + " +0000";
this.date = DATE_FORMAT.parse(dateString);
} catch (Exception ex) {
BugLog.getInstance().bug("Couldn't parse date " + dateString);
}
}
public void setDate(Date date, String dateString) {
this.dateString = dateString;
this.date = date;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getLines() {
return lines;
}
public void setLines(String lines) {
this.lines = lines;
}
public String getCommitID() {
return commitID;
}
public void setCommitID(String commitID) {
this.commitID = commitID;
}
/**
* Returns how many lines were added in this revision.
*/
public int getAddedLines() {
if (lines != null) {
int start = lines.indexOf('+');
int end = lines.indexOf(' ');
if (start >= 0 && end > start) {
String added = lines.substring(start + 1, end);
try {
int toReturn = Integer.parseInt(added);
return toReturn;
} catch (NumberFormatException exc) {
// TODO BUGLog..
}
}
}
return 0;
}
public int getRemovedLines() {
if (lines != null) {
int start = lines.indexOf('-');
if (start >= 0) {
String removed = lines.substring(start + 1);
try {
int toReturn = Integer.parseInt(removed);
return toReturn;
} catch (NumberFormatException exc) {
// TODO BUGLog..
}
}
}
return 0;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getBranches() {
return branches;
}
public void setBranches(String branches) {
this.branches = branches;
}
}
}