Hi,
i am writing a Jython program, comprised of 2 Java files (HeadRevisionReachedException.java,SVNLogging.java) and 3 Jython (SVNLogs2DBParser.py, DBTablesHandler.py, launch.py) files. The exception file has nothing special... The program reads SVN log data and updates a DB. The reading of SVN data is done by the Java part.
launch.py: used for launching the program
Code:
from SVNLogs2DBParser import SVNLogs2DBParser
parser=SVNLogs2DBParser()
parser.getLogsLoop()
SVNLogs2DBParser.py: parses SVN log data and handles them to the "DBTablesHandler.py", in order for the DB to be updated. HERE'S THE ERROR
I THINK from my little Jython experience; by using the debugger, i found out, that "svnLogging_" isn't instantiated and that later somewhere in the program a "java.lang.NullPointerException" is thrown!
Code:
#!/usr/bin/env jython
import pdb
from paxosk.sqoss.java.svn import HeadRevisionReachedException
from paxosk.sqoss.java.svn import SVNLogging
from java.util import List
from org.tmatesoft.svn.core import SVNLogEntry
from DBTablesHandler import DBTablesHandler
###############################################################################
PIVOT=100 #Read the 1st 100 logs from the SVN, the next 100,..., the n-th 100.
#The PIVOT parameter depends on how much we want to stress our RAM.
SVN_REPOS="file:///home/kostas/sqo-oss/svn/kde"
###############################################################################
pdb.set_trace()
class SVNLogs2DBParser:
def __init__(self):
svnLogging_=SVNLogging(SVN_REPOS)
dbTable_=DBTablesHandler()
cmterID_=0
projID_=0
Commiter_={}
Commit_={}
Project_={}
ProjectVersion_={}
#reads all the revision logs (traversing them PIVOT at a time) and
#processes each log entry
def getLogsLoop(self):
#PROBLEMS START HERE, METHODS ARE CALLED ON NULL (svnLogging_)
while svnLogging_.getCurrentRevision()!=svnLogging_.getLatestRevision():
entryList_.clear()
try:
entryList_=svnLogging_.getNextLogs(PIVOT);
except HeadRevisionReachedException:
print "Attempting to go over the HEAD revision..."
for entry in entryList:
print "processing new SVN entry..."
processLogEntry(entry)
#processes each log entry
#
#"entry" is of type SVNLogEntry. See SVNKit API
#"changedPaths" is returned as a java.util.HashMap of paths
#"entry.getDates()" returns a java.util.Date object
def processLogEntry(self, entry):
revision = int(entry.getRevision())
commiter = str(entry.getAuthor())
datetime = getTimeStamp(entry.getDate())
message = str(entry.getMessage())
changedPaths = entry.getChangedPaths()
#array passed for updating the Commiter DB table
Commiter_[0] = cmterID_
Commiter_[1] = commiter
dbTable_.updateCommiterTable(Commiter_)
#array passed for updating the Commit DB table
Commit_[0] = revision
Commit_[1] = datetime
Commit_[2] = commiterID_
Commit_[3] = "" #properties
Commit_[4] = message
Commit_[5] = getNumberOfLines(message)
dbTable_.updateCommitTable(Commit_)
ProjectVersion_[0]=projID_
ProjectVersion_[1]=""
ProjectVersion_[2]=""
dbTable_.updateProjectVersionTable(ProjectVersion_)
Project[0]=projID_
Project[1]=""
Project[2]=""
Project[3]=""
Project[4]=""
dbTable_.updateProjectTable(Project_)
cmterID_+=1
projID_+1
##############################HELPER##METHODS###############################
#Returns a timestamp String form a (depreceated) java.util.Date object;
#of the form YYYYMMDDHHMMSS
def getTimeStamp(self,datetime):
return datetime.getYear()+datetime.getMonth()+datetime.getDay()+ \
datetime.getHours()+datetime.getMinutes()+datetime.getSeconds()
#Reads a string and counts the newline chars
def getNumberOfLines(self, text):
n=0
for line in text.readLines():
n+=0
return n
def createFileID(self, filepath):
pathParts=filepath.split("/");
filename=pathParts[len(pathParts)-1]
##############################HELPER##METHODS###############################
DBTablesHandler: handles the connection to the DB
Code:
#!/usr/bin/env jython
from com.ziclix.python.sql import zxJDBC
#This module handles the communication to the MySQL DB;
#-opens the TCP connection to the already created DB and
#-passes the instances of the fields to each table, by using the
#corresponding function
###############################################################################
SERVER_HOSTNAME='localhost';
DB_NAME='sqoss';
USER='kostas';
PASSWD='XYZ';
PORT=3306;
###############################################################################
class DBTablesHandler:
###
#connect to the MySQL server by using the given parameters
#and get a cursor
def __init__(self):
params = {}
params['serverName']=SERVER_HOSTNAME
params['databaseName']=DB_NAME
params['user']=USER
params['password']=PASSWD
params['port']=PORT
db = apply(zxJDBC.connectx, ("com.mysql.jdbc.jdbc2.optional.MysqlDataSource",), params)
dbcursor_=db.cursor()
print "Connection established to SVN repository..."
#Commiter is a 2 field table;
#Commiter[0]: pk_cmterID --> PRIMARY KEY
#Commiter[1]: cmterName
def updateCommiterTable(self, Commiter):
dbcursor_.execute("INSERT INTO Commiter (pk_cmterID,cmterName) VALUES (" \
+Commiter[0]+","+Commiter[1]+")")
#Commit is a 7 field table;
#Commit[0]:pk_cmitID --> PRIMARY KEY
#Commit[1]:cmitTime
#Commit[2]:fk_cmterID --> REFERENCES Commiter(pk_cmterID)
#Commit[3]:cmitProperties
#Commit[4]:cmitComment
#Commit[5]:cmitCommentLines
#Commit[6]:fk_projID --> REFERENCES ProjectVersion(pfk_projID)
#Commit[7]:pk_cmitID
def updateCommitTable(self, Commit):
dbcursor_.execute("INSERT INTO Commit (pfk_commitID,commitTime,fk_commiterID,commitComment,commitCommentLines) VALUES (" \
+Commit[0]+","+Commit[1]+","+Commit[2]+","+Commit[3]+","+Commit[4]+")")
#Project is a 6 field table;
#Project[0]: pk_projID --> PRIMARY KEY
#Project[1]: projName
#Project[2]: projWebsite
#Project[3]: projContactPoint
#Project[4]: projSrcPath
#Project[5]: projMailPath
def updateProjectTable(self, Project):
dbcursor_.execute("INSERT INTO File (pfk_projectID,projectName,projectWebsite,projectContactPoint,projectSrcPath,projectMailPath) VALUES (" \
+Project[0]+","+Project[1]+","+Project[2]+","+Project[3]+","+Project[4]+","+Project[5]+")")
#ProjectVersion is a 3 field table;
#ProjectVersion[0]: pfk_projID --> PRIMARY KEY, REFERENCES Project(pk_projID)
#ProjectVersion[1]: projName
#ProjectVersion[2]: projVersion
def updateProjectVersionTable(self,ProjectVersion):
dbcursor_.execute("INSERT INTO ProjectVersion (pfk_projID,projName,projVersion) VALUES (" \
+ProjectVersion[0]+ProjectVersion[1]+ProjectVersion[2]+")");
SVNLogging.java: reads the logs from the repository. I have tested it with a main method and works OK
Code:
package paxosk.sqoss.java.svn;
/* This class iteratively or at once, returns the SVN logging objects for the range of the
* revisions (form "revision number start" to "revision number end") of the repository specified.
*
* USE:
* ************
* SVNLogging l=new SVNLogging("file:///home/kostas/sqo-oss/svn/kde");
*
* int pivot=100;
*
* while (l.getCurrentRevision()!=l.getLatestRevisionNumber()) {
* l.getNextLogs(pivot);
* System.out.println(l.toString());
* }
*/
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.*;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
public class SVNLogging
{
//////////////////////////CONSTRUCTOR FIELDS/////////////////////////////////////
//the URL of the repository
private String url_="";
//the username, if required; anonymous by default
private String username_="anonymous";
//the password, if required; anonymous by default
private String passwd_="anonymous";
//////////////////////////CONSTRUCTOR FIELDS/////////////////////////////////////
//current revision;
private long currentRevision_=0;
//HEAD revision number
private long headRevision_=0;
//the repository
private SVNRepository repository_=null;
//the collection of the log entries of the given range retrieved
private Collection<SVNLogEntry> logEntries_=null;
////////////////////////////////CONSTRUCTORS/////////////////////////////////////
public SVNLogging(String url)
{
url_=url;
setupLibrary();
openRepository();
findLatestRevisionNumber();
}//SVNTarget
public SVNLogging(String url,String username, String passwd)
{
this(url);
username_=username;
passwd_=passwd;
setupLibrary();
openRepository();
findLatestRevisionNumber();
}//SVNTarget
////////////////////////////////CONSTRUCTORS/////////////////////////////////////
////////////////////////////////////HELPERS//////////////////////////////////////
/* initialize and open the repository; uses the given username and password
*/
private void openRepository()
{
try
{
repository_= SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url_));
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username_, passwd_);
repository_.setAuthenticationManager(authManager);
}
catch (SVNException svne)
{
System.err.println("Failed to open repositort "+ url_ + ": " + svne.getMessage());
System.exit(-1);
}
}//openRepository
/* updates the variable showing to the latest revision
*/
private void findLatestRevisionNumber()
{
try
{
headRevision_ = repository_.getLatestRevision();
}
catch (SVNException svne)
{
System.err.println("error while fetching the latest repository revision: " + svne.getMessage());
System.exit(1);
}
}//getLatestRevision
/* Initializes the library to work with a repository via
* different protocols.
*/
private void setupLibrary()
{
//Use over http:// and https://
DAVRepositoryFactory.setup();
//Use over svn:// and svn+xxx://
SVNRepositoryFactoryImpl.setup();
//Use over file:///
FSRepositoryFactory.setup();
}//setupLibrary
////////////////////////////////////HELPERS//////////////////////////////////////
/* Returns a collection of the next number of log entries requested. The
* caller must always check, by using the corresponding methods, if the current
* revision equals the head revision
* yes? finished
* no? continues
*
* If the head revision has already been reached and we attempt to read more
* log entries, a HeadRevisionReachedException is thrown.
*
* Note: The collection returned can be casted to a linked list; the return type
* is an upper casting from a LinkedList
*/
public Collection<SVNLogEntry> getNextLogs(long revNum) throws HeadRevisionReachedException
{
if (currentRevision_==headRevision_)
{
throw new HeadRevisionReachedException("The log for the head revision has already " +
"been read");
}
//clear the collection from the previous entries
if (logEntries_!=null) {
logEntries_.clear();
}
//if the number of revisions requested to be returned drives us
//out of the head revision number, then return as many as possible
//revisions including the head one.
if (currentRevision_+revNum > headRevision_)
{
revNum=headRevision_-currentRevision_;
}
try
{
logEntries_= repository_.log(new String[] {""}, null, currentRevision_,
currentRevision_+revNum, true, true);
}
catch (SVNException svne)
{
System.out.println("failed to retrieve log info (start revision: "+currentRevision_+" end revision: "+
(currentRevision_+revNum)+")\n for "+ url_ + ": " + svne.getMessage());
System.exit(-1);
}
currentRevision_+=revNum;
return logEntries_;
}//getNextLogs
public long getLatestRevisionNumber()
{
return headRevision_;
}//getLatestRevisionNumber
public long getCurrentRevision()
{
return currentRevision_;
}//getCurrentRevision
/* Returns a verbose string representation of the last log entries requested.
* (code from the examples of svnkit.com)
*/
public String toString()
{
String s="";
for (Iterator entries = logEntries_.iterator(); entries.hasNext();)
{
SVNLogEntry logEntry = (SVNLogEntry) entries.next();
s=s+"---------------------------------------------\n";
s=s+"revision: " + logEntry.getRevision()+'\n';
s=s+"author: " + logEntry.getAuthor()+'\n';
s=s+"date: " + logEntry.getDate()+'\n';
s=s+"log message: " + logEntry.getMessage()+'\n';
if (logEntry.getChangedPaths().size() > 0)
{
s=s+'\n';
s=s+"changed paths:\n";
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths
.hasNext();)
{
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry
.getChangedPaths().get(changedPaths.next());
s=s+" "
+ entryPath.getType()
+ " "
+ entryPath.getPath()
+ ((entryPath.getCopyPath() != null) ? " (from "
+ entryPath.getCopyPath() + " revision "
+ entryPath.getCopyRevision() + ")" : "\n");
}
}
}
return s;
}//toString
// public static void main(String[] args) throws Exception
// {
// SVNLogging l=new SVNLogging("file:///home/kostas/sqo-oss/svn/kde");
//
// int pivot=100;
//
// while (l.getCurrentRevision()!=l.getLatestRevisionNumber())
// {
// l.getNextLogs(pivot);
// System.out.println(l.toString());
// }
// }
// public static void main(String[] args) throws Exception
// {
// SVNLogging l=new SVNLogging("file:///home/kostas/sqo-oss/svn/kde");
//
// int pivot=100;
//
// while (l.getCurrentRevision()!=l.getLatestRevisionNumber())
// {
// java.util.LinkedList<SVNLogEntry> list=(java.util.LinkedList<SVNLogEntry>)l.getNextLogs(pivot);
//
// for (SVNLogEntry entry: list)
// System.out.println(entry);
// }
// }
}
Can somebody help? Thanks