[21919] | 1 | package org.greenstone.admin.guiext;
|
---|
| 2 |
|
---|
| 3 | import org.w3c.dom.Element;
|
---|
| 4 |
|
---|
| 5 | import java.util.ArrayList;
|
---|
| 6 |
|
---|
| 7 | import java.io.File;
|
---|
| 8 |
|
---|
| 9 | import javax.swing.JButton;
|
---|
| 10 | import javax.swing.JFrame;
|
---|
| 11 | import javax.swing.JOptionPane;
|
---|
| 12 | import javax.swing.JTextArea;
|
---|
| 13 | import javax.swing.JLabel;
|
---|
| 14 | import javax.swing.JPanel;
|
---|
| 15 |
|
---|
| 16 | import java.awt.BorderLayout;
|
---|
| 17 |
|
---|
| 18 | import java.awt.event.ActionListener;
|
---|
| 19 | import java.awt.event.ActionEvent;
|
---|
| 20 |
|
---|
| 21 | import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
|
---|
| 22 | import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
|
---|
| 23 | import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
|
---|
| 24 | import org.tmatesoft.svn.core.wc.SVNClientManager;
|
---|
| 25 | import org.tmatesoft.svn.core.wc.SVNWCUtil;
|
---|
| 26 | import org.tmatesoft.svn.core.wc.SVNUpdateClient;
|
---|
| 27 | import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
---|
| 28 | import org.tmatesoft.svn.core.wc.SVNEvent;
|
---|
| 29 | import org.tmatesoft.svn.core.wc.SVNEventAction;
|
---|
| 30 | import org.tmatesoft.svn.core.wc.SVNRevision;
|
---|
| 31 | import org.tmatesoft.svn.core.wc.SVNStatusType;
|
---|
| 32 | import org.tmatesoft.svn.core.SVNURL;
|
---|
| 33 | import org.tmatesoft.svn.core.SVNException;
|
---|
| 34 | import org.tmatesoft.svn.core.SVNDepth;
|
---|
| 35 | import org.tmatesoft.svn.core.SVNCancelException;
|
---|
| 36 |
|
---|
| 37 | import org.greenstone.admin.GAI;
|
---|
| 38 | import org.greenstone.admin.LoggedMessageArea;
|
---|
| 39 |
|
---|
| 40 | public class DownloadStep extends Step
|
---|
| 41 | {
|
---|
| 42 | Source _mainSource = null;
|
---|
| 43 | Source[] _auxSources = null;
|
---|
| 44 | LoggedMessageArea _messageArea = new LoggedMessageArea(this.getClass());
|
---|
| 45 |
|
---|
| 46 | public DownloadStep(SequenceList parent)
|
---|
| 47 | {
|
---|
| 48 | super("AUTOMATIC_DOWNLOAD", "Download Extension", "", "", parent);
|
---|
| 49 |
|
---|
| 50 | ExtensionInformation info = _parent.getParent();
|
---|
| 51 |
|
---|
[23582] | 52 | _mainSource = new Source("svn", info.getBaseURL() + info.getFileStem() + "/trunk/src", "", this);
|
---|
[21919] | 53 |
|
---|
| 54 | _button.addActionListener(new DownloadButtonListener());
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | public DownloadStep(Element downloadStepElement, SequenceList parent)
|
---|
| 58 | {
|
---|
| 59 | super(downloadStepElement, parent);
|
---|
| 60 |
|
---|
| 61 | if(downloadStepElement != null){
|
---|
| 62 | Element mainSourceElement = ExtXMLHelper.getSingleChildElement(downloadStepElement, ExtXMLHelper.MAIN_SOURCE, true);
|
---|
| 63 | if(mainSourceElement == null){
|
---|
| 64 | System.err.println("This download <" + ExtXMLHelper.STEP + "> element has no <" + ExtXMLHelper.MAIN_SOURCE + "> element");
|
---|
| 65 | }
|
---|
| 66 | else{
|
---|
| 67 | _mainSource = new Source(mainSourceElement, this);
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | Element[] auxSourceElements = ExtXMLHelper.getMultipleChildElements(downloadStepElement, ExtXMLHelper.AUX_SOURCE, false);
|
---|
| 71 | if(auxSourceElements != null){
|
---|
| 72 | _auxSources = new Source[auxSourceElements.length];
|
---|
| 73 | for(int i = 0; i < auxSourceElements.length; i++){
|
---|
| 74 | _auxSources[i] = new Source(auxSourceElements[i], this);
|
---|
| 75 | }
|
---|
| 76 | }
|
---|
| 77 |
|
---|
| 78 | _button = new JButton(_label);
|
---|
| 79 | _button.setEnabled(false);
|
---|
| 80 | _button.addActionListener(new DownloadButtonListener());
|
---|
| 81 | }
|
---|
| 82 | else{
|
---|
| 83 | System.err.println("This download <" + ExtXMLHelper.STEP + "> element is null");
|
---|
| 84 | }
|
---|
| 85 | }
|
---|
| 86 |
|
---|
| 87 | public class DownloadButtonListener implements ActionListener
|
---|
| 88 | {
|
---|
| 89 | boolean _svnInitialised = false;
|
---|
| 90 | public DownloadButtonListener()
|
---|
| 91 | {
|
---|
| 92 | if(!_svnInitialised){
|
---|
| 93 | //Setup the SVN client system
|
---|
| 94 | DAVRepositoryFactory.setup();
|
---|
| 95 | SVNRepositoryFactoryImpl.setup();
|
---|
| 96 | FSRepositoryFactory.setup();
|
---|
| 97 | }
|
---|
| 98 | _svnInitialised = true;
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | public void actionPerformed(ActionEvent e)
|
---|
| 102 | {
|
---|
| 103 | _button.setEnabled(false);
|
---|
| 104 | _button.setText("Downloading...");
|
---|
| 105 |
|
---|
| 106 | DownloadThread downloadThread = new DownloadThread();
|
---|
| 107 | downloadThread.start();
|
---|
| 108 | }
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | public class DownloadThread extends Thread
|
---|
| 112 | {
|
---|
| 113 | public void run()
|
---|
| 114 | {
|
---|
| 115 | ExtensionInformation info = _parent.getParent();
|
---|
| 116 |
|
---|
| 117 | JPanel panel = new JPanel();
|
---|
| 118 | panel.setLayout(new BorderLayout());
|
---|
| 119 | panel.add(_messageArea, BorderLayout.CENTER);
|
---|
| 120 | info.changeExtPane(panel);
|
---|
| 121 |
|
---|
| 122 | String fileStem = info.getFileStem();
|
---|
| 123 | String defaultDownloadLocation = GAI.getGSDL3ExtensionHome() + System.getProperty("file.separator") + fileStem;
|
---|
| 124 |
|
---|
[25635] | 125 | ArrayList<Source> sourceElements = new ArrayList<Source>();
|
---|
[21919] | 126 | sourceElements.add(_mainSource);
|
---|
| 127 |
|
---|
| 128 | if(_auxSources != null){
|
---|
| 129 | for(int i = 0; i < _auxSources.length; i++){
|
---|
| 130 | sourceElements.add(_auxSources[i]);
|
---|
| 131 | }
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | for(int i = 0; i < sourceElements.size(); i++){
|
---|
| 135 |
|
---|
[25635] | 136 | Source currentSource = sourceElements.get(i);
|
---|
[21919] | 137 | String destinationFolder = null;
|
---|
| 138 |
|
---|
| 139 | if(currentSource.getMethod().equals("svn")){
|
---|
| 140 | String name = "";
|
---|
| 141 | String password = "";
|
---|
| 142 |
|
---|
| 143 | //Setup the SVN client
|
---|
| 144 | SVNClientManager svnManager = SVNClientManager.newInstance(SVNWCUtil.createDefaultOptions(true), name, password);
|
---|
| 145 | SVNUpdateClient svnCheckout = svnManager.getUpdateClient();
|
---|
| 146 | svnCheckout.setEventHandler(new SVNCheckoutEventHandler());
|
---|
| 147 | svnCheckout.setIgnoreExternals(false);
|
---|
| 148 |
|
---|
[21954] | 149 | //The i != 0 enforces that the mainSource should always go to the default download location
|
---|
| 150 | if(i != 0 && !currentSource.getFolder().equals("")){
|
---|
[21919] | 151 | destinationFolder = currentSource.getFolder();
|
---|
| 152 | }
|
---|
| 153 | else{
|
---|
| 154 | destinationFolder = defaultDownloadLocation;
|
---|
| 155 | }
|
---|
| 156 |
|
---|
| 157 | //Check if the directory already exists. If it does exist then as the use if they wish to delete it
|
---|
| 158 | File wcDir = new File(destinationFolder);
|
---|
| 159 | if (wcDir.exists()) {
|
---|
| 160 |
|
---|
| 161 | Object[] option = {"Continue","Cancel"};
|
---|
| 162 | int n = JOptionPane.showOptionDialog(new JFrame(),"The folder for this extension already exists, continuing will remove all the files within this folder before proceeding.","Attention",
|
---|
| 163 | JOptionPane.YES_NO_CANCEL_OPTION,
|
---|
| 164 | JOptionPane.QUESTION_MESSAGE,
|
---|
| 165 | null,
|
---|
| 166 | option,
|
---|
| 167 | option[0]);
|
---|
| 168 | if(n == 0){
|
---|
| 169 | ExtPane.deleteDir(wcDir);
|
---|
| 170 | }
|
---|
| 171 | else{
|
---|
| 172 | _button.setEnabled(true);
|
---|
| 173 | _button.setText(_label);
|
---|
| 174 | return;
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 | wcDir.mkdirs();
|
---|
| 178 |
|
---|
| 179 | //Perform the specified checkout
|
---|
| 180 | String url = currentSource.getURL();
|
---|
| 181 | try{
|
---|
| 182 | SVNURL repositoryURL = SVNURL.parseURIEncoded(url);
|
---|
| 183 | long x = svnCheckout.doCheckout(repositoryURL, wcDir, SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, true);
|
---|
| 184 | }
|
---|
| 185 | catch(SVNException ex){
|
---|
| 186 | ex.printStackTrace();
|
---|
| 187 | _messageArea.append("Error retrieving file from SVN");
|
---|
| 188 | _button.setEnabled(true);
|
---|
| 189 | _button.setText(_label);
|
---|
| 190 | return;
|
---|
| 191 | }
|
---|
| 192 | }
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 | _button.setEnabled(true);
|
---|
| 196 | _button.setText(_label);
|
---|
| 197 | _parent.registerStepCompletion(DownloadStep.this);
|
---|
| 198 | }
|
---|
| 199 | }
|
---|
| 200 |
|
---|
| 201 | public class SVNCheckoutEventHandler implements ISVNEventHandler
|
---|
| 202 | {
|
---|
| 203 | public void handleEvent(SVNEvent event, double progress)
|
---|
| 204 | {
|
---|
| 205 | /*
|
---|
| 206 | * Gets the current action. An action is represented by SVNEventAction.
|
---|
| 207 | * In case of an update an action can be determined via comparing
|
---|
| 208 | * SVNEvent.getAction() and SVNEventAction.UPDATE_-like constants.
|
---|
| 209 | */
|
---|
| 210 |
|
---|
| 211 | //_messageArea.append(" event occurs");
|
---|
| 212 | SVNEventAction action = event.getAction();
|
---|
| 213 | String pathChangeType = " ";
|
---|
| 214 | if (action == SVNEventAction.UPDATE_ADD) {
|
---|
| 215 | /*
|
---|
| 216 | * the item was added
|
---|
| 217 | */
|
---|
| 218 | pathChangeType = "A";
|
---|
| 219 | } else if (action == SVNEventAction.UPDATE_DELETE) {
|
---|
| 220 | /*
|
---|
| 221 | * the item was deleted
|
---|
| 222 | */
|
---|
| 223 | pathChangeType = "D";
|
---|
| 224 | } else if (action == SVNEventAction.UPDATE_UPDATE) {
|
---|
| 225 | /*
|
---|
| 226 | * Find out in details what state the item is (after having been
|
---|
| 227 | * updated).
|
---|
| 228 | *
|
---|
| 229 | * Gets the status of file/directory item contents. It is
|
---|
| 230 | * SVNStatusType who contains information on the state of an item.
|
---|
| 231 | */
|
---|
| 232 | SVNStatusType contentsStatus = event.getContentsStatus();
|
---|
| 233 | if (contentsStatus == SVNStatusType.CHANGED) {
|
---|
| 234 | /*
|
---|
| 235 | * the item was modified in the repository (got the changes
|
---|
| 236 | * from the repository
|
---|
| 237 | */
|
---|
| 238 | pathChangeType = "U";
|
---|
| 239 | }else if (contentsStatus == SVNStatusType.CONFLICTED) {
|
---|
| 240 | /*
|
---|
| 241 | * The file item is in a state of Conflict. That is, changes
|
---|
| 242 | * received from the repository during an update, overlap with
|
---|
| 243 | * local changes the user has in his working copy.
|
---|
| 244 | */
|
---|
| 245 | pathChangeType = "C";
|
---|
| 246 | } else if (contentsStatus == SVNStatusType.MERGED) {
|
---|
| 247 | /*
|
---|
| 248 | * The file item was merGed (those changes that came from the
|
---|
| 249 | * repository did not overlap local changes and were merged
|
---|
| 250 | * into the file).
|
---|
| 251 | */
|
---|
| 252 | pathChangeType = "G";
|
---|
| 253 | }
|
---|
| 254 | } else if (action == SVNEventAction.UPDATE_EXTERNAL) {
|
---|
| 255 | /*for externals definitions*/
|
---|
| 256 | _messageArea.append("Fetching external item into '"
|
---|
| 257 | + event.getFile().getAbsolutePath() + "'");
|
---|
| 258 | _messageArea.append("External at revision " + event.getRevision());
|
---|
| 259 | return;
|
---|
| 260 | } else if (action == SVNEventAction.UPDATE_COMPLETED) {
|
---|
| 261 | /*
|
---|
| 262 | * Updating the working copy is completed. Prints out the revision.
|
---|
| 263 | */
|
---|
| 264 | //_messageArea.append("At revision " + event.getRevision());
|
---|
| 265 | _messageArea.append("At revision " + event.getRevision()+"\n");
|
---|
| 266 | //_messageArea.append("The extension ("+ _extensionName +") has been downloaded to the local folder: \n"+ _destination +"\n"); //xxxxx
|
---|
| 267 | _messageArea.setSelectionEnd(_messageArea.getDocument().getLength());
|
---|
| 268 | return;
|
---|
| 269 | } else if (action == SVNEventAction.ADD){
|
---|
| 270 | _messageArea.append("A " + event.getURL().getPath());
|
---|
| 271 | return;
|
---|
| 272 | } else if (action == SVNEventAction.DELETE){
|
---|
| 273 | _messageArea.append("D " + event.getURL().getPath());
|
---|
| 274 | return;
|
---|
| 275 | } else if (action == SVNEventAction.LOCKED){
|
---|
| 276 | _messageArea.append("L " + event.getURL().getPath());
|
---|
| 277 | return;
|
---|
| 278 | } else if (action == SVNEventAction.LOCK_FAILED){
|
---|
| 279 | _messageArea.append("failed to lock " + event.getURL().getPath());
|
---|
| 280 | return;
|
---|
| 281 | }
|
---|
| 282 |
|
---|
| 283 | /*
|
---|
| 284 | * Now getting the status of properties of an item. SVNStatusType also
|
---|
| 285 | * contains information on the properties state.
|
---|
| 286 | */
|
---|
| 287 | SVNStatusType propertiesStatus = event.getPropertiesStatus();
|
---|
| 288 | /*
|
---|
| 289 | * At first consider properties are normal (unchanged).
|
---|
| 290 | */
|
---|
| 291 | String propertiesChangeType = " ";
|
---|
| 292 | if (propertiesStatus == SVNStatusType.CHANGED) {
|
---|
| 293 | /*
|
---|
| 294 | * Properties were updated.
|
---|
| 295 | */
|
---|
| 296 | propertiesChangeType = "U";
|
---|
| 297 | } else if (propertiesStatus == SVNStatusType.CONFLICTED) {
|
---|
| 298 | /*
|
---|
| 299 | * Properties are in conflict with the repository.
|
---|
| 300 | */
|
---|
| 301 | propertiesChangeType = "C";
|
---|
| 302 | } else if (propertiesStatus == SVNStatusType.MERGED) {
|
---|
| 303 | /*
|
---|
| 304 | * Properties that came from the repository were merged with the
|
---|
| 305 | * local ones.
|
---|
| 306 | */
|
---|
| 307 | propertiesChangeType = "G";
|
---|
| 308 | }
|
---|
| 309 |
|
---|
| 310 | /*
|
---|
| 311 | * Gets the status of the lock.
|
---|
| 312 | */
|
---|
| 313 | String lockLabel = " ";
|
---|
| 314 | SVNStatusType lockType = event.getLockStatus();
|
---|
| 315 |
|
---|
| 316 | if (lockType == SVNStatusType.LOCK_UNLOCKED) {
|
---|
| 317 | /*
|
---|
| 318 | * The lock is broken by someone.
|
---|
| 319 | */
|
---|
| 320 | lockLabel = "B";
|
---|
| 321 | }
|
---|
| 322 |
|
---|
| 323 | /*
|
---|
| 324 | System.err.println("pathChangeType = " + pathChangeType);
|
---|
| 325 | System.err.println("propertiesChangeType = " + propertiesChangeType);
|
---|
| 326 | System.err.println("lockLabel = " + lockLabel);
|
---|
| 327 | System.err.println("event = " + event);
|
---|
| 328 | System.err.println("event.getURL = " + event.getURL());
|
---|
| 329 | */
|
---|
| 330 |
|
---|
| 331 | final String content = pathChangeType
|
---|
| 332 | + propertiesChangeType
|
---|
| 333 | + lockLabel
|
---|
| 334 | + " "
|
---|
| 335 | + (event.getURL() == null ? "" : event.getURL().getPath()) + "\n";
|
---|
| 336 |
|
---|
| 337 | _messageArea.append(content);
|
---|
| 338 | _messageArea.setSelectionEnd(_messageArea.getDocument().getLength());
|
---|
| 339 | }
|
---|
| 340 |
|
---|
| 341 | public void checkCancelled() throws SVNCancelException
|
---|
| 342 | {
|
---|
| 343 | }
|
---|
| 344 | }
|
---|
| 345 | } |
---|