package com.perforce.common.process;
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.perforce.common.ExitCode;
import com.perforce.common.Stats;
import com.perforce.common.StatsType;
import com.perforce.common.asset.TypeMap;
import com.perforce.config.CFG;
import com.perforce.config.Config;
import com.perforce.config.UserMapping;
import com.perforce.config.Version;
import com.perforce.svn.change.ChangeInterface;
import com.perforce.svn.change.ChangeMap;
public abstract class ProcessChange implements Callable<Integer> {
private Logger logger = LoggerFactory.getLogger(ProcessChange.class);
private ChangeInterface currentChange = null;
private boolean stop = false;
private boolean clean = true;
private ExitCode runState = ExitCode.OK;
/**
* This method is extended by the specific implementation of ProcessChange
*
* @throws Exception
*/
protected void processChange() throws Exception {
logger.error("common.ProcessChange.processChange() should be extended");
throw new RuntimeException();
}
/**
* Core run method for conversions
*
*/
@Override
public Integer call() throws Exception {
try {
// register exception hook
Runtime.getRuntime().addShutdownHook(new CleanShutdown());
// run conversion
runSingle();
// log summary
if (logger.isInfoEnabled()) {
String summary = Stats.summary(currentChange.getChange());
logger.info(summary);
}
// check for warnings
long warn = Stats.getLong(StatsType.warningCount);
if (warn > 0) {
runState = ExitCode.WARNING;
}
} catch (Throwable e) {
// catch any remaining throws
logger.error("Caught exception on exit", e);
runState = ExitCode.EXCEPTION;
} finally {
// save state and shutdown cleanly
saveState();
clean = true;
}
return runState.value();
}
/**
* Runs conversion as single threaded (blocking) Used for UI and test cases
*
* @throws Throwable
*/
public void runSingle() throws Exception {
// Initialise common environment
processInit();
// Call processChange implementation
processChange();
}
private void processInit() throws Exception {
// Setup stats counters
Stats.setDefault();
// Log version of jar file
Version ver = new Version();
logger.info("jar build version: \t" + ver.getVersion());
// Check JRE for symlink support
if (Config.isImportMode()) {
String javaVer = System.getProperty("java.version");
logger.info("java.version:\t\t" + javaVer);
if (!javaVer.startsWith("1.7")) {
throw new RuntimeException("JRE 1.7.x required for Import mode");
}
}
// Set unicode handling for p4-java
System.setProperty("com.perforce.p4java.defaultCharset", "UTF-8");
// Initialise changeMap tables from existing file
String changeMapFile = (String) Config.get(CFG.CHANGE_MAP);
ChangeMap.load(changeMapFile);
// Initialise user mapping, if required
String userMapFile = (String) Config.get(CFG.USER_MAP);
UserMapping.load(userMapFile);
// Initialise type map, if required
String typeMapFile = (String) Config.get(CFG.TYPE_MAP);
TypeMap.load(typeMapFile);
// Report operation mode
if (Config.isImportMode()) {
logger.info("conversion mode: \tIMPORT (front-door)\n");
} else {
logger.info("conversion mode: \tCONVERT (back-door)\n");
}
}
/**
* Submit current pending change or delete if empty changelist
*
* @throws Exception
*/
public void submit() throws Exception {
boolean skip = (Boolean) Config.get(CFG.P4_SKIP_EMPTY);
// Submit or delete the current pending change.
if (currentChange != null) {
// logging details
Stats.inc(StatsType.currentRevision);
if (logger.isInfoEnabled()) {
StringBuffer log = new StringBuffer();
log.append("mapping: r" + currentChange.getSvnRevision());
log.append(" => @" + currentChange.getChange() + "\n");
logger.info(log.toString());
}
// update stats
Stats.addUser(currentChange.getUser());
// map change to subversion revision
ChangeMap.add(currentChange.getSvnRevision(),
currentChange.getChange());
// check if current change has revisions
int revCount = currentChange.getNumberOfRevisions();
if (skip && revCount == 0) {
currentChange.delete();
} else {
currentChange.submit();
}
}
}
/**
* Closes the journal and flushes to disk, typically at the end of
* conversion
*
* @throws Exception
*/
public void close() throws Exception {
currentChange.close();
}
/**
* Private method to save thread state on exit.
*
*/
private void saveState() {
try {
if (logger.isDebugEnabled()) {
logger.debug("Saving changeMap...");
}
ChangeMap.store((String) Config.get(CFG.CHANGE_MAP));
} catch (Exception e) {
logger.error("Unable to saving changeMap", e);
}
}
/**
* Private shutdown hook to exit cleanly after exception.
*
*/
private class CleanShutdown extends Thread {
public void run() {
stop = true;
runState = ExitCode.SHUTDOWN;
if (logger.isInfoEnabled()) {
logger.info("Caught EXIT shutting down ...");
}
while (!clean) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
logger.error("InterruptedException", e);
}
}
}
}
public boolean isStop() {
return stop;
}
public void setClean(boolean clean) {
this.clean = clean;
}
public ChangeInterface getCurrentChange() {
return currentChange;
}
public void setCurrentChange(ChangeInterface currentChange) {
this.currentChange = currentChange;
}
}
# |
Change |
User |
Description |
Committed |
|
#1
|
10825 |
Paul Allen |
Branching using paul_allen.p4convert |
|
|
//guest/perforce_software/p4convert/src/com/perforce/common/process/ProcessChange.java |
#1
|
9807 |
Paul Allen |
Initial import of p4-convert (from change 894340) |
|
|