Salesforce.com Data Download via Java Swing, RSSBus JDBC Driver, and Apache Commons Daemon

I recently developed an application that synchronizes Salesforce.com data to a local PC. The application is developed in Java using the Swing graphical framework and uses a Salesforce.com JDBC driver provided by RSSBus. The application stores Salesforce.com credentials and synchronization interval timing data in a Java properties file. The application allows non-graphical execution via the “nogui” command argument. I also include an Apache Commons Daemon class and script that allows running the application as a service.

Here’s the main application class. This class can be executed via a command prompt by “java -jar myfile.jar nogui”.


 

package com.zydecodigital.emb;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.OutputStreamWriter;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/**
* Sync Salesforce data to local folder.
* @author rtoepfer
*
*/
public class SalesforceSync implements Runnable {

// If true do not create GUI
public boolean bCommandLine = false;

String m_strHomeDirectory;
String m_strZDDirectory;
String m_strLogFile;
String m_strPropertiesFile;
String m_strOS;
String m_strSyncInterval;

// Create the window.
JFrame frame = new JFrame();

// Declare components
JButton btnLog = new JButton("Open Log File");
JButton btnFile = new JButton("Destination Folder");
JFileChooser fileChooser = new JFileChooser();
JLabel lblSync = new JLabel("Sync Time (24 Hour):");
JTextField tfSyncInterval = new JTextField("24:00");
JButton btnSaveSyncInterval = new JButton("Save");
JButton btnSync = new JButton("Synchronize Local Data");
JLabel lblCredentials = new JLabel("Salesforce Credentials (User/Pass/Token):");
JTextField tfUser = new JTextField();
JPasswordField tfPass = new JPasswordField();
JPasswordField tfToken = new JPasswordField();

// Salesforce JDBC connection
Connection conn = null;
Properties conn_prop = null;

public SalesforceSync(boolean bCommandLine) {

this.bCommandLine = bCommandLine;
this.m_strOS = System.getProperty("os.name");

this.setFiles("");

// RSSBus JDBC connection properties
this.conn_prop = new Properties();

this.readProperties();

// DEBUG properties
// this.conn_prop.setProperty("Logfile", this.m_strDirectory + "/JDBC_Debug.txt");
// this.conn_prop.setProperty("Verbosity", "1");
// this.conn_prop.setProperty("RecordToFile", this.m_strDirectory + "/JDBC_Debug_Socket.txt");
}

/**
* Invokes Java Swing event dispatch thread
* @param args
*/
public static void main(String[] args) {
SalesforceSync se = null;
if (args.length > 0) {
if (args[0].contains("nogui")) {
se = new SalesforceSync(true);
} else {
se = new SalesforceSync(false);
}
} else {
se = new SalesforceSync(false);
}

SwingUtilities.invokeLater(se);
}

void readProperties() {
// Load properties file
File fileProp = new File(this.m_strPropertiesFile);
try {
this.conn_prop.load(new FileInputStream(fileProp));

this.m_strZDDirectory = this.conn_prop.getProperty("ZD-Directory", this.m_strZDDirectory);
this.m_strSyncInterval = this.conn_prop.getProperty("Sync Interval", "24:00");

} catch (Exception e) {
}
}

void setFiles(String strZDDirectory) {

// Set directory structure

// Home folder
String strHome = System.getProperty("user.home");
this.m_strHomeDirectory = strHome + File.separator + "ZydecoDigital";
this.m_strLogFile = this.m_strHomeDirectory + File.separator + "log.txt";
this.m_strPropertiesFile = this.m_strHomeDirectory + File.separator + "prop.txt";

// ZD save folder
if (strZDDirectory.isEmpty()) {
this.m_strZDDirectory = this.m_strHomeDirectory;
} else {
this.m_strZDDirectory = strZDDirectory;
}
}

void saveProperties() {

try {
// get user name, password, token, sync interval, directory
SalesforceSync.this.conn_prop.setProperty("User", SalesforceSync.this.tfUser.getText());
SalesforceSync.this.conn_prop.setProperty("Password", String.copyValueOf(SalesforceSync.this.tfPass.getPassword()));
SalesforceSync.this.conn_prop.setProperty("Access Token", String.copyValueOf(SalesforceSync.this.tfToken.getPassword()));
SalesforceSync.this.conn_prop.setProperty("Sync Interval", SalesforceSync.this.tfSyncInterval.getText());
SalesforceSync.this.conn_prop.setProperty("ZD-Directory", SalesforceSync.this.m_strZDDirectory);

// save properties to text file
File fileProp = new File(SalesforceSync.this.m_strPropertiesFile);
if (!fileProp.exists()) {
// test whether the directory exists
File zdDirectory = new File(SalesforceSync.this.m_strZDDirectory);
if (!zdDirectory.exists())
zdDirectory.mkdirs();
fileProp.createNewFile();
}
OutputStream out = new FileOutputStream(fileProp);
SalesforceSync.this.conn_prop.store(out, "Saved on " + DateFormat.getDateInstance().format(new Date()));
} catch (Exception e1) {
JOptionPane.showMessageDialog(SalesforceSync.this.frame, e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}

/**
* Connect to Salesforce via RSSBus JDBC driver and download all opportunity data
*/
synchronized void syncToSalesforce() {
try {
// save dialog fields to properties file
if (this.bCommandLine)
this.readProperties(); // re-read properties in case this call is from periodic scheduled task
else
this.saveProperties();

// read last entry date in log file (latest update is pre-pended to file)
BufferedReader bufferLogFile = null;
String strLine = "";

// open log file
File logFile = new File(this.m_strLogFile);
if (logFile.exists()) {
bufferLogFile = new BufferedReader(new FileReader(logFile));
strLine = bufferLogFile.readLine();
if (strLine == null)
strLine = "";
}

// parse date from first line
// Ex: '[2000-01-01] Synced...'
String strLastSyncDate = null;
if (!strLine.isEmpty()) {
strLastSyncDate = strLine.substring(1, 11);
if (strLastSyncDate.length() != 10)
strLastSyncDate = null;
}

// create temp log file
File fileTemp = File.createTempFile("zydeco", "tmp");
fileTemp.deleteOnExit();
BufferedWriter writerTemp = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileTemp)));

// connect to Salesforce
if (this.conn == null) {
this.conn = DriverManager.getConnection("jdbc:salesforce", this.conn_prop);
}

// pull all opportunities on and after log date
Statement dbStatement = this.conn.createStatement();
String strSql;
ResultSet results = null;
if (strLastSyncDate != null)
strSql = "SELECT * FROM Opportunity WHERE CloseDate >= '" + strLastSyncDate + "' AND (StageName = 'Closed Won' OR StageName = 'Closed Lost')";
else
strSql = "SELECT * FROM Opportunity WHERE StageName = 'Closed Won' OR StageName = 'Closed Lost'";

boolean status = dbStatement.execute(strSql);
if (status) {

results = dbStatement.getResultSet();

// store results in arraylist
filltable data = new filltable(this.conn, results);

// get indices of columns
int iOpportunityIdIx = data.getColumnIndex("Id");
int iEmbProjectNameIx = data.getColumnIndex("EMB_Project_Name__c");
int iEmbProjectId = data.getColumnIndex("Assigned_EMB_Project_Number__c");
int iEmbProposalId = data.getColumnIndex("Assigned_EMB_Proposal_Number__c");

// save name of each opportunity synced to Log file
String strOpportunitiesSaved = "";

// folder name will have year as prefix
Date date = new Date();
SimpleDateFormat folderDateFormat = new SimpleDateFormat("y");
String strFolderDatePrefix = folderDateFormat.format(date);

// Create folders if they do not exist, save opportunity and proposal data
int i, j;
for (i = 0; i < data.getRowCount(); i++) { String strOpportunityId; String strEMB_ProjectName; String strEMB_ProjectId; String strEMB_ProposalId; strOpportunityId = data.getValueAt(i, iOpportunityIdIx).toString(); strEMB_ProjectName = (String) data.getValueAt(i, iEmbProjectNameIx).toString(); strEMB_ProjectId = (String) data.getValueAt(i, iEmbProjectId).toString(); strEMB_ProposalId = (String) data.getValueAt(i, iEmbProposalId).toString(); // if no proposal id do not continue // NOTE: for Salesforce developer account dummy data will not have this field set; however, in production // this field is required for all accounts if (strEMB_ProposalId.isEmpty()) continue; // create folder name String strFolderName = strFolderDatePrefix + "-" + strEMB_ProjectId + "-" + strEMB_ProjectName; String strFolderPath = SalesforceSync.this.m_strZDDirectory + File.separator + strFolderName; // create folder if it doesn't exist File folder = new File(strFolderPath); if (!folder.exists()) folder.mkdirs(); // create CSV text file of opportunity data String strCsvFilePath = strFolderPath + File.separator + "Data.csv"; File opportunityCSV = new File(strCsvFilePath); data.storeAsCSV(i, opportunityCSV); // save percent construction line items String strPercentConstructionSql = "SELECT * FROM Opportunity_Percent_Construction_Item__c WHERE Opportunity__c = '" + strOpportunityId + "'"; Statement dbPercentConstructionStatement = this.conn.createStatement(); boolean pcStatus = dbPercentConstructionStatement.execute(strPercentConstructionSql); if (pcStatus) { ResultSet pcResults = dbPercentConstructionStatement.getResultSet(); filltable pcData = new filltable(this.conn, pcResults); if (pcData.getRowCount() > 0) {
// save to CSV file
String strPCCsvFilePath = strFolderPath + File.separator + "LineItemsData.csv";
File opportunityPCCSV = new File(strPCCsvFilePath);
pcData.storeAsCSV(i, opportunityPCCSV);
}
}

// save all proposals
CallableStatement cs = null;
cs = this.conn.prepareCall("DownloadAttachment");

// IN params
cs.setString("ObjectId", strOpportunityId);

// due to a bug in RSSBus JDBC driver not using File.separator for file paths we
// need to add slash for POSIX based systems
if (!this.m_strOS.contains("Windows"))
cs.setString("LocalPath", strFolderPath + "/");
else
cs.setString("LocalPath", strFolderPath);
cs.execute();

// remove backslash at beginning of filename on Linux/Apple machines
if (!this.m_strOS.contains("Windows")) {
File[] arrFiles = folder.listFiles();
for (j = 0; j < arrFiles.length; j++) {
String strFileName = arrFiles[j].getName();
if (strFileName.startsWith("\\")) {
String strNewFileName = strFileName.substring(1);
File fileNew = new File(strFolderPath + File.separator + strNewFileName);
arrFiles[j].renameTo(fileNew);
}
}
}

// log opportunity saves
if (i < data.getRowCount() - 1)
strOpportunitiesSaved += "'" + strFolderName + "', ";
else
strOpportunitiesSaved += "'" + strFolderName + "'";

} // end for each opportunities loop

// update log file
SimpleDateFormat dateLogFormat = new SimpleDateFormat("yyyy-MM-dd");
String strLogMsg = "[" + dateLogFormat.format(date) + "]" + " Synced Opportunities: " + strOpportunitiesSaved + "\n";
writerTemp.write(strLogMsg);

// read our log file into our temp file (already read first line above)
if (!strLine.isEmpty()) {
do {
if (strLine != null)
strLine += "\n";
writerTemp.write(strLine);
strLine = bufferLogFile.readLine();
} while(strLine != null);
}
writerTemp.flush();

// rename temp file to log file
if(bufferLogFile != null)
bufferLogFile.close();
if(logFile.exists())
logFile.delete();
fileTemp.renameTo(new File(this.m_strLogFile));

} // end if result status
} catch (Exception e1) {
JOptionPane.showMessageDialog(this.frame, e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}

/**
* Open the Log file in text editor
*/
class ButtonLogListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
File f = new File(SalesforceSync.this.m_strLogFile);
if (f.exists()) {
String strCmd;
// open text file in gedit/Notepad
if (SalesforceSync.this.m_strOS.contains("Windows")) {
strCmd = "notepad.exe " + SalesforceSync.this.m_strLogFile;
} else if (SalesforceSync.this.m_strOS.contains("Mac")) {
strCmd = "open -t " + SalesforceSync.this.m_strLogFile;
} else {
strCmd = "gedit " + SalesforceSync.this.m_strLogFile;
}
try {
@SuppressWarnings("unused")
Process tr = Runtime.getRuntime().exec(strCmd);
} catch (IOException e1) {
JOptionPane.showMessageDialog(SalesforceSync.this.frame, "Could not open log file", "Error", JOptionPane.ERROR_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(SalesforceSync.this.frame, "Log file does not exist", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}

/**
* Select a file to store synced data to
* Note: application will only download data based on last log file entry not based
* on data that exists in new directory
*/
class ButtonFileListener implements ActionListener {
public void actionPerformed(ActionEvent e) {

// setup dialog
SalesforceSync.this.fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
File zdDir = new File(SalesforceSync.this.m_strZDDirectory);
SalesforceSync.this.fileChooser.setCurrentDirectory(zdDir);

// open dialog
int nReturnVal = SalesforceSync.this.fileChooser.showOpenDialog(null);
if (nReturnVal == JFileChooser.APPROVE_OPTION) {

File dir = SalesforceSync.this.fileChooser.getSelectedFile();
SalesforceSync.this.m_strZDDirectory = dir.getAbsolutePath();

SalesforceSync.this.saveProperties();
}
}
}

/**
* Save sync interval change to properties file
*/
class ButtonSaveListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
SalesforceSync.this.saveProperties();
}
}

/**
* Download Salesforce data
*/
class ButtonSyncListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// set sync button text
SalesforceSync.this.btnSync.setEnabled(false);
SalesforceSync.this.btnSync.setText("Synchronizing...Please Wait");

// sync Salesforce data
SalesforceSync.this.syncToSalesforce();

// enable button
SalesforceSync.this.btnSync.setEnabled(true);
SalesforceSync.this.btnSync.setText("Synchronize Local Data");
}
}

@Override
public void run() {

// no GUI
if (this.bCommandLine) {
// sync Salesforce data
this.syncToSalesforce();
}

// show GUI
else {
// Use absolute positioning
frame.setLayout(null);

// Size components
btnLog.setBounds(25, 25, 140, 25);
btnFile.setBounds(180, 25, 180, 25);
lblSync.setBounds(25, 75, 200, lblSync.getPreferredSize().height);
tfSyncInterval.setBounds(200, 70, 50, tfSyncInterval.getPreferredSize().height + 10);
btnSaveSyncInterval.setBounds(290, 70, 70, 25);
btnSync.setBounds(25, 120, 300, 25);
lblCredentials.setBounds(25, 175, 300, lblSync.getPreferredSize().height);
tfUser.setBounds(25, 200, 250, tfUser.getPreferredSize().height + 10);
tfPass.setBounds(25, 245, 250, tfPass.getPreferredSize().height + 10);
tfToken.setBounds(25, 290, 250, tfToken.getPreferredSize().height + 10);

// Add listeners
ButtonLogListener logListener = new ButtonLogListener();
btnLog.addActionListener(logListener);
ButtonFileListener fileChooseListener = new ButtonFileListener();
btnFile.addActionListener(fileChooseListener);
ButtonSaveListener saveListener = new ButtonSaveListener();
btnSaveSyncInterval.addActionListener(saveListener);
ButtonSyncListener syncListener = new ButtonSyncListener();
btnSync.addActionListener(syncListener);

// Get saved values
String strUser = this.conn_prop.getProperty("User", "User Name");
String strPassword = this.conn_prop.getProperty("Password", "");
String strAccessToken = this.conn_prop.getProperty("Access Token", "");
String strSyncInterval = this.conn_prop.getProperty("Sync Interval", "24:00");

tfUser.setText(strUser);
tfPass.setText(strPassword);
tfToken.setText(strAccessToken);
tfSyncInterval.setText(strSyncInterval);

// Add components to frame
frame.add(btnLog);
frame.add(btnFile);
frame.add(lblSync);
frame.add(tfSyncInterval);
frame.add(btnSaveSyncInterval);
frame.add(btnSync);
frame.add(lblCredentials);
frame.add(tfUser);
frame.add(tfPass);
frame.add(tfToken);

// Sets the behavior for when the window is closed.
frame.setTitle("EMB Salesforce Sync Utility");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null); // centers the window

// Display frame
frame.setVisible(true);
}
}

}

The following class was copied from the RSSBus JDBC demo folder. The class basically takes a java.sql.ResultSet object and copies the data to an ArrayList. Several functions were added to the class by Zydeco.

package com.zydecodigital.emb;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
* This class has been copied from the RSSBus Salesforce JDBC driver demo folder.
* @author rtoepfer
*
*/
@SuppressWarnings("serial")
public class filltable extends AbstractTableModel {
private ResultSet rs;
private int rowCount;
private int columnCount;
@SuppressWarnings("rawtypes")
private ArrayList data=new ArrayList();
@SuppressWarnings({ "unused", "rawtypes" })
private List updateRows = new ArrayList();
@SuppressWarnings({ "unused", "rawtypes" })
private List insertRows = new ArrayList();
@SuppressWarnings("unused")
private Connection conn=null;

/**
* Constructor
* @param conn
* @param _rs
* @throws Exception
*/
public filltable(Connection conn, ResultSet _rs) throws Exception
{
this.conn = conn;
setRS(_rs);
}

/**
* Set result set to internal result set. Store each value in an array as default
* result set does not allow cursor manipulation.
*
* @param _rs
* @throws Exception
*/
@SuppressWarnings("unchecked")
public void setRS(ResultSet _rs) throws Exception
{
this.rs=_rs;
ResultSetMetaData metaData=_rs.getMetaData();
rowCount=0;
columnCount=metaData.getColumnCount();
while(_rs.next()){
Object[] row=new Object[columnCount];
for(int j=0;j<columnCount;j++){
row[j]=_rs.getObject(j+1);
}
data.add(row);
rowCount++;
}
}

public int getColumnCount(){
return columnCount;
}

public int getRowCount(){
return rowCount;
}

/**
* Returns value from ArrayList data. Uses 0 based indices.
*/
public Object getValueAt(int rowIndex, int columnIndex){
Object[] row=(Object[]) data.get(rowIndex);
Object datum = row[columnIndex];
if(datum == null)
datum = new String("");
return datum;
}

/**
* Return the column name for a column index that uses 0 based indices.
* Note ResultSetMetaData class uses 1 based indices.
*/
public String getColumnName(int columnIndex) {
try{
ResultSetMetaData metaData=rs.getMetaData();
return metaData.getColumnName(columnIndex+1);
}catch(Exception e){
e.printStackTrace();
return null;
}
}

/**
* Get 0 based column index for a given column name.
* @param strDesiredColumnName
* @return
*/
public int getColumnIndex(String strDesiredColumnName) {
int columnIx = -1;
ResultSetMetaData metaData;
int columnCount = this.getColumnCount();
int i;
String strColumnName;

try {
metaData=rs.getMetaData();
for(i=1; i<=columnCount;i++) {
strColumnName = metaData.getColumnName(i);

if(strDesiredColumnName.equals(strColumnName)) {
columnIx = i-1;
break;
}
}
} catch(Exception e){
e.printStackTrace();
}

return columnIx;
}

/**
* Store a row as a CSV file, uses 0 based indices.
* @param row Row to store; if -1 store all rows.
* @param f File to save CSV to.
* @throws IOException
* @throws SQLException
*/
public void storeAsCSV(int row, File f) throws IOException,
SQLException {
FileOutputStream fos;
Writer out = new OutputStreamWriter(new BufferedOutputStream(fos = new FileOutputStream(f, false)));
int i, j;
int nColumnCount = this.getColumnCount();
int nRowCount = this.getRowCount();

// write columns
for (i=0; i<nColumnCount; i++) {
out.append(CSVQuote(this.getColumnName(i)));
if (i < nColumnCount - 1) out.append(","); } out.append("\r\n"); // write data int startRow = 0; int endRow = nRowCount; if(row >= 0 && row < this.getRowCount()) {
startRow = row;
endRow = row + 1;
}

for (i=startRow; i<endRow; i++) {
for (j=0; j<nColumnCount; j++) {
out.append(CSVQuote(this.getValueAt(i, j).toString()));
if (i < nColumnCount - 1)
out.append(",");
}
out.append("\r\n");
}
out.append("\r\n");

// close file
out.flush();
fos.close();
}

private CharSequence CSVQuote(String value) {
return "\"" + value + "\"";
}

}

Here's the Apache Commons Daemon class and associated Linux shell script to interact with the service.

package com.zydecodigital.emb;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.commons.daemon.*;

public class Launcher implements Daemon {

SwingGUI syncSalesforce = null;
ScheduledExecutorService scheduler = null;
ScheduledFuture<?> schedulerHandle = null;

public static void main(String[] args) {
}

@Override
public void destroy() {
}

@Override
public void init(DaemonContext arg0) throws DaemonInitException, Exception {
// sync salesforce data
syncSalesforce = new SwingGUI(true);
scheduler = Executors.newScheduledThreadPool(1);
}

@Override
public void start() throws Exception {

if(schedulerHandle == null) {
Calendar now = Calendar.getInstance();

int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
//int hour = now.get(Calendar.HOUR_OF_DAY); // 24 hour format
//int minute = now.get(Calendar.MINUTE);
//int seconds = now.get(Calendar.SECOND);

Calendar future = Calendar.getInstance();
future.set(year, month, day, 24, 0);

long delay = future.getTimeInMillis() - now.getTimeInMillis();

schedulerHandle = scheduler.scheduleAtFixedRate(syncSalesforce, delay, 24*60*60*1000, TimeUnit.MILLISECONDS);
}
}

@Override
public void stop() throws Exception {
if(schedulerHandle != null) {
scheduler.schedule(new Runnable() {
public void run() {
schedulerHandle.cancel(true);
}
}, 0, TimeUnit.SECONDS);
}
}

}

#!/bin/sh

# Setup variables
EXEC=/usr/bin/jsvc
JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")
CLASS_PATH="/home/rtoepfer/workspace/EMB-Salesforce-Service/lib/commons-daemon-1.0.15.jar":"/home/rtoepfer/workspace/EMB-Salesforce-Service/lib/RSSBus JDBC Driver for Salesforce V3/lib/rssbus.jdbc.salesforce.jar"
CLASS=Launcher.main
USER=rtoepfer
PID=/tmp/ZydecoDigital-EMB-Salesforce.pid
LOG_OUT=/tmp/ZydecoDigital-EMB-Salesforce.out
LOG_ERR=/tmp/ZydecoDigital-EMB-Salesforce.err

do_exec()
{
$EXEC -home "$JAVA_HOME" -cp $CLASS_PATH -user $USER -outfile $LOG_OUT -errfile $LOG_ERR -pidfile $PID $1 $CLASS
}

case "$1" in
start)
do_exec
;;
stop)
do_exec "-stop"
;;
restart)
if [ -f "$PID" ]; then
do_exec "-stop"
do_exec
else
echo "service not running, will do nothing"
exit 1
fi
;;
*)
echo "usage: daemon {start|stop|restart}" >&2
exit 3
;;
esac

Leave a Reply

Your email address will not be published. Required fields are marked *