SmartSync - Network Enabled File Synchronizer |
---|
This tutorial is a quick introduction to SmartSync. It includes useful
examples to learn the basic concepts of the architecture. To run the examples, you need a
Java 2 runtime environment (see java.sun.com), a Servlet
container like Tomcat and at
least the evaluation version of SmartSync.
The full source code of all examples and its compiled versions are also available in that
package. So, don't hesitate to get a free copy of it!
At the end of this tutorial, you are able to deploy, run and configure SmartSync. Please
refer to the API documentation and to the protocol definition for further reading.
Well, before you start, have a quick look at the overview
document. It gives you an idea of SmartSyncs functionality.
Package Structure
Document Roots
Operation Modes
Server Deployment
Client Integration
Progress Monitoring
li.netcat.smartsync |
This is the only package used by SmartSync. It has to be deployed on the client as well as on the server. |
There are actually three document roots (directories) involved in the synchronization process. They are named as follows:
Depending on the configuration, the client has three different modes of operation:
docroot
, the client operates
as follows: docroot_tmp
(work directory) as a sister of docroot
(archive directory)docroot_tmp
by copying data from the work
directory and receiving data from the reference directory.docroot
to docroot_old
and docroot_tmp
to docroot
.docroot_tmp
to docroot_new
. In this mode, an external
script has to make sure to rename docroot_new
to docroot
before
startup. Make sure, that the application has sufficient rights to read and write files in these
directories. Furthermore, the client and the server implementations try to create a
checksum-file called chksum.crc
in the document roots for performance
reasons. Also not necessary, you may delete this file whenever you want, but you may not
modify it. This can lead to an inconsistent state.
The server part of SmartSync is the SmartSyncServer servlet that has to be deployed into a servlet container. Here is an example of a deployment descriptor (web.xml):
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>SmartSync</display-name> <description>Servlet for directory snchronization.</description> <servlet> <servlet-name>SmartSyncServer</servlet-name> <description>This is the SmartSync servlet</description> <servlet-class>li.netcat.smartsync.SmartSyncServer</servlet-class> <init-param> <param-name>reference-directory</param-name> <param-value>c:\temp\server</param-value> </init-param> <load-on-startup>5</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SmartSyncServer</servlet-name> <url-pattern>/SmartSyncServer</url-pattern> </servlet-mapping> </web-app>
Notice the initial parameter reference-directory, it has to be configured to point to the reference directory. Make also sure that the servlet container has access to the SmartSync package.
Supposed that the SmartSyncServer has been deployed on the local host on port 8080 and home directory smartsync, the following client code will synchronize the given directory:
public static void main(String[] args) {
try {
SmartSyncClient client = new SmartSyncClient();
client.synchronize(
new
URL("http://localhost:8080/smartsync/SmartSyncServer"),
new File("c:\\temp\\client"));
}
catch (IOException x) {
x.printStackTrace();
}
}
The synchronize method returns true or false if an update was available or not.
Interactive clients give the user a view into the progress of the operation and the
possibility to abort the operation. Since the look of a progress monitor must be
individual to each application, no progress monitor is included in the SmartSync package.
Nevertheless, the following sections describes, how to build and integrate a custom
progress monitor.
An implementation of the interface EventMonitor can be added to the SmartSyncClient with the following command:
client.addEventMonitor(new SmartSyncMonitor());
Here comes the code of the custom event monitor:
public class SmartSyncMonitor extends DialogPanel implements EventMonitor { private JFrame _frame; private InfoPanel _infoPanel; private TaskPanel _taskPanel; private JButton _cancelButton; private JButton _exitButton; private boolean _abort = false; public SmartSyncMonitor() { _infoPanel = new InfoPanel(); _taskPanel = new TaskPanel(); JPanel content = new JPanel(new BorderLayout(5, 5)); content.add(_infoPanel, BorderLayout.NORTH); content.add(_taskPanel, BorderLayout.CENTER); setContent(content); addButton(_cancelButton = new JButton("Cancel")); _cancelButton.setEnabled(false); _cancelButton.addActionListener(new CancelListener()); addButton(_exitButton = new JButton("Exit")); _exitButton.addActionListener(new ExitListener()); } public JFrame open() { _frame = new JFrame("SmartSync Monitor"); _frame.setContentPane(this); _frame.pack(); Rectangle bounds = _frame.getGraphicsConfiguration().getBounds(); _frame.setLocation(bounds.x + (bounds.width - _frame.getWidth())/2, bounds.y + (bounds.height - _frame.getHeight())/3); _frame.setVisible(true); _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // due to bug 4030718 (http://developer.java.sun.com/developer/bugParade/bugs/4030718.html) _frame.toFront(); return _frame; } //// interface EventMonitor public void onStart(URL remoteDirectory, File localDirectory) { _infoPanel.setTexts(remoteDirectory.toString(), localDirectory.toString()); _taskPanel.setText("Checking for updates..."); open(); } public void onTaskAnnounce(Task task) { _taskPanel.addTask(task); } public void onTaskStart(Task task) { _cancelButton.setEnabled(true); _taskPanel.setCurrentTask(task); } public void onProgress(TransferProgress progress) { _taskPanel.setTransferProgress(progress); } public void onTaskCompletion(Task task) { _taskPanel.setTaskCompleted(task); } public void onSuccess(boolean updateDone) { _cancelButton.setEnabled(false); if (updateDone) { JOptionPane.showMessageDialog(this, "The directory structure has been updated successfully", "Information", JOptionPane.INFORMATION_MESSAGE); } else { _taskPanel.setText("No update available."); } } public void onIOException(IOException iox, Task task) { _cancelButton.setEnabled(false); if (task != null) { _taskPanel.setTaskFailed(task); } JOptionPane.showMessageDialog(this, iox.getMessage(), "Warning", JOptionPane.WARNING_MESSAGE); } public void onAbortCheck() throws UserAbortIOException { if (_abort) { throw new UserAbortIOException(); } } //// inner classes private class CancelListener implements ActionListener { public void actionPerformed(ActionEvent event) { _abort = true; _cancelButton.setEnabled(false); } } private class ExitListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.exit(0); } } }
Beside the details of the layout, the main aspect is the implementation of the interface EventMonitor. An other object worth mentioning is the TransferProgress that includes all data needed to display the progress bar with some statistic information:
... private JLabel _transferRate; private JLabel _completedFiles; private JLabel _completedTraffic; private JLabel _remainTime; private JLabel _remainFiles; private JLabel _remainTraffic; private JProgressBar _progressBar; ... public void setTransferProgress(TransferProgress progress) { _transferRate.setText(formatTransferRate(progress.getTransferRate())); _completedFiles.setText(formatNrOfFiles(progress.getCompletedFiles())); _completedTraffic.setText(formatTraffic(progress.getCompletedTraffic())); _remainTime.setText(formatRemainingTime(progress.getRemainingTime())); _remainFiles.setText(formatNrOfFiles(progress.getRemainingFiles())); _remainTraffic.setText(formatTraffic(progress.getRemainingTraffic())); _progressBar.setValue((int)(progress.getProgress() * 100)); } ...
Please refer to the complete sources in the example package for more details.
Copyright © 2003 NetCat AG. All rights reserved.