/plugins/SVNPlugin/tags/1.3.0/src/ise/plugin/svn/action/CopyAction.java

# · Java · 325 lines · 233 code · 24 blank · 68 comment · 55 complexity · a674f4e37d58179f34d15519522f541e MD5 · raw file

  1. /*
  2. Copyright (c) 2007, Dale Anson
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without modification,
  5. are permitted provided that the following conditions are met:
  6. * Redistributions of source code must retain the above copyright notice,
  7. this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright notice,
  9. this list of conditions and the following disclaimer in the documentation
  10. and/or other materials provided with the distribution.
  11. * Neither the name of the author nor the names of its contributors
  12. may be used to endorse or promote products derived from this software without
  13. specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  18. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21. ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. package ise.plugin.svn.action;
  26. import ise.plugin.svn.gui.OutputPanel;
  27. import ise.plugin.svn.SVNPlugin;
  28. import ise.plugin.svn.command.Copy;
  29. import ise.plugin.svn.data.AddResults;
  30. import ise.plugin.svn.data.CopyData;
  31. import ise.plugin.svn.gui.AddResultsPanel;
  32. import ise.plugin.svn.gui.CopyResultsPanel;
  33. import ise.plugin.svn.gui.ErrorPanel;
  34. import ise.plugin.svn.io.ConsolePrintStream;
  35. import ise.plugin.svn.library.swingworker.*;
  36. import java.awt.event.ActionEvent;
  37. import java.io.*;
  38. import java.util.*;
  39. import java.util.logging.*;
  40. import javax.swing.JPanel;
  41. import org.gjt.sp.jedit.Buffer;
  42. import org.gjt.sp.jedit.EditBus;
  43. import org.gjt.sp.jedit.jEdit;
  44. import org.gjt.sp.jedit.View;
  45. import org.gjt.sp.jedit.msg.BufferUpdate;
  46. import org.tmatesoft.svn.core.SVNCommitInfo;
  47. import org.tmatesoft.svn.core.SVNURL;
  48. import org.tmatesoft.svn.core.wc.SVNCopySource;
  49. /**
  50. * ActionListener to perform an svn copy.
  51. * This is not dependent on ProjectViewer.
  52. */
  53. public class CopyAction extends SVNAction {
  54. private CopyData data = null;
  55. private String title = "Copy";
  56. private static final int W2W = 1;
  57. private static final int W2U = 2;
  58. private static final int U2W = 3;
  59. private static final int U2U = 4;
  60. /**
  61. * @param view the View in which to display results
  62. * @param data CopyData object containing the info for a copy of some sort
  63. */
  64. public CopyAction( View view, CopyData data ) {
  65. super( view, "Copy" );
  66. if ( data == null )
  67. throw new IllegalArgumentException( "data may not be null" );
  68. this.data = data;
  69. this.title = data.getTitle();
  70. setUsername(data.getUsername());
  71. setPassword(data.getPassword());
  72. }
  73. public void actionPerformed( ActionEvent ae ) {
  74. if ( data != null ) {
  75. // TODO: if copying to a url, need username/password for destination
  76. // repository, which isn't necessarily the same as the username/password
  77. // for the source.
  78. if ( getUsername() == null ) {
  79. SVNCopySource[] sources = data.getSourceFiles();
  80. verifyLogin(sources != null && sources.length > 0 && sources[0].getFile() != null ? sources[0].getFile().getAbsolutePath() : null );
  81. if ( isCanceled() ) {
  82. return ;
  83. }
  84. }
  85. data.setUsername( getUsername() );
  86. data.setPassword( getPassword() );
  87. data.setOut( new ConsolePrintStream( getView() ) );
  88. getView().getDockableWindowManager().showDockableWindow( "subversion" );
  89. final OutputPanel panel = SVNPlugin.getOutputPanel( getView() );
  90. panel.showConsole();
  91. final Logger logger = panel.getLogger();
  92. String log_msg = title.equals( "Tag" ) ? "Tagging" : title + "ing";
  93. logger.log( Level.INFO, log_msg );
  94. for ( Handler handler : logger.getHandlers() ) {
  95. handler.flush();
  96. }
  97. /**
  98. * Used to copy or move either a working file to another working file or to the
  99. * repository, or to move a repository file or directory to a working file or to
  100. * another repository location. To recap, this class can copy:
  101. * working copy -> working copy
  102. * working copy -> repository
  103. * repository -> working copy
  104. * repository -> repository
  105. */
  106. class Runner extends SwingWorker<TreeMap<String, SVNCommitInfo>, Object> {
  107. private int where2where;
  108. private String errorMessage = null;
  109. @Override
  110. public TreeMap<String, SVNCommitInfo> doInBackground() {
  111. TreeMap<String, SVNCommitInfo> results = new TreeMap<String, SVNCommitInfo>();
  112. try {
  113. SVNCopySource[] sources = data.getSourceFiles();
  114. if ( sources != null ) {
  115. for ( SVNCopySource source : sources ) {
  116. if ( source == null ) {
  117. continue;
  118. }
  119. File file = source.getFile();
  120. CopyData cd = new CopyData();
  121. cd.setUsername(data.getUsername());
  122. cd.setPassword(data.getPassword());
  123. cd.setSourceFile( file );
  124. cd.setRevision( data.getRevision() );
  125. String destination = "";
  126. if ( data.getDestinationFile() != null ) {
  127. // working copy -> working copy
  128. where2where = W2W;
  129. if ( data.getSourceFiles().length > 1 ) {
  130. checkDestination( data.getDestinationFile() );
  131. }
  132. // if destination is a directory, figure out
  133. // the new file names of the copies
  134. if ( data.getDestinationFile().isDirectory() ) {
  135. File f = new File( data.getDestinationFile(), file.getName() );
  136. destination = f.getAbsolutePath();
  137. }
  138. else {
  139. destination = data.getDestinationFile().getAbsolutePath();
  140. }
  141. cd.setDestinationFile( data.getDestinationFile() );
  142. }
  143. else if ( data.getDestinationURL() != null ) {
  144. // working copy -> repository
  145. where2where = W2U;
  146. if ( data.getSourceFiles().length > 1 ) {
  147. // must be copying to a directory -- TODO: how to check
  148. // destination is actually a remote directory?
  149. // For now, assume directory and append filename.
  150. destination = data.getDestinationURL().toString() + "/" + file.getName();
  151. }
  152. else {
  153. destination = data.getDestinationURL().toString();
  154. }
  155. cd.setDestinationURL( SVNURL.parseURIDecoded( destination ) );
  156. }
  157. cd.setOut( data.getOut() );
  158. cd.setMessage( data.getMessage() );
  159. Copy copy = new Copy();
  160. SVNCommitInfo result = copy.copy( cd );
  161. if ( result != null ) {
  162. results.put( destination, result );
  163. }
  164. }
  165. }
  166. else if ( data.getSourceURLs() != null ) {
  167. for ( SVNCopySource source : data.getSourceURLs() ) {
  168. if ( source == null ) {
  169. continue;
  170. }
  171. SVNURL url = source.getURL();
  172. CopyData cd = new CopyData();
  173. cd.setUsername(data.getUsername());
  174. cd.setPassword(data.getPassword());
  175. String destination = "";
  176. cd.setSourceURL( url );
  177. cd.setRevision( data.getRevision() );
  178. if ( data.getDestinationFile() != null ) {
  179. // repository -> working file
  180. where2where = U2W;
  181. if ( data.getSourceURLs().length > 1 ) {
  182. checkDestination( data.getDestinationFile() );
  183. }
  184. // if destination is a directory, figure out
  185. // the new file names of the copies
  186. if ( data.getDestinationFile().isDirectory() ) {
  187. String path = url.getPath();
  188. String name = path.substring( path.lastIndexOf( "/" ) );
  189. File f = new File( data.getDestinationFile(), name );
  190. destination = f.getAbsolutePath();
  191. }
  192. else {
  193. destination = data.getDestinationFile().getAbsolutePath();
  194. }
  195. destination = data.getDestinationFile().getAbsolutePath();
  196. cd.setDestinationFile( data.getDestinationFile() );
  197. }
  198. else if ( data.getDestinationURL() != null ) {
  199. // repository -> repository
  200. where2where = U2U;
  201. destination = data.getDestinationURL().toString();
  202. cd.setDestinationURL( data.getDestinationURL() );
  203. }
  204. cd.setOut( data.getOut() );
  205. cd.setMessage( data.getMessage() );
  206. Copy copy = new Copy();
  207. SVNCommitInfo result = copy.copy( cd );
  208. if ( result != null ) {
  209. results.put( destination, result );
  210. }
  211. }
  212. }
  213. }
  214. catch ( Exception e ) {
  215. errorMessage = e.getMessage();
  216. data.getOut().printError( errorMessage );
  217. e.printStackTrace();
  218. }
  219. finally {
  220. data.getOut().close();
  221. }
  222. return results;
  223. }
  224. @Override
  225. public boolean cancel( boolean mayInterruptIfRunning ) {
  226. boolean cancelled = super.cancel( mayInterruptIfRunning );
  227. if ( cancelled ) {
  228. data.getOut().printError( "Stopped 'Copy' action." );
  229. data.getOut().close();
  230. }
  231. else {
  232. data.getOut().printError( "Unable to stop 'Copy' action." );
  233. }
  234. return cancelled;
  235. }
  236. @Override
  237. protected void done() {
  238. try {
  239. if ( errorMessage != null ) {
  240. JPanel error_panel = new ErrorPanel( errorMessage );
  241. panel.addTab( jEdit.getProperty( "ips.Copy_Error", "Copy Error" ), error_panel );
  242. return ;
  243. }
  244. TreeMap<String, SVNCommitInfo> results = get();
  245. switch ( where2where ) {
  246. case W2W:
  247. case U2W: {
  248. // SVNCommitInfo in results will be null in these
  249. // cases since there is no actual commit. These
  250. // files will be scheduled for svn add.
  251. AddResults ar = new AddResults();
  252. for ( String path : results.keySet() ) {
  253. ar.addPath( path );
  254. }
  255. JPanel results_panel = new AddResultsPanel( ar, AddResultsPanel.ADD, getView(), data.getUsername(), data.getPassword() );
  256. panel.addTab( title, results_panel );
  257. // open the file(s) and signal ProjectViewer to possibly add the file
  258. for ( String path : results.keySet() ) {
  259. File f = new File( path );
  260. if ( !f.isDirectory() ) {
  261. Buffer buffer = jEdit.openFile( getView(), path );
  262. BufferUpdate bu = new BufferUpdate( buffer, getView(), BufferUpdate.SAVED );
  263. EditBus.send( bu );
  264. }
  265. }
  266. }
  267. break;
  268. case W2U:
  269. case U2U: {
  270. // these cases result in an immediate commit, so
  271. // the SVNCommitInfo objects in the map are valid
  272. JPanel results_panel = new CopyResultsPanel( results, data.getDestinationURL().toString(), false );
  273. panel.addTab( title, results_panel );
  274. }
  275. break;
  276. default:
  277. // this shouldn't happen, so I'll just quietly
  278. // ignore this case
  279. }
  280. }
  281. catch ( Exception e ) {
  282. // ignored
  283. e.printStackTrace();
  284. }
  285. }
  286. private void checkDestination( File destination ) throws Exception {
  287. // destination must be a directory and must exist
  288. if ( !destination.exists() || !destination.isDirectory() ) {
  289. throw new Exception( "Invalid destination: " + destination.getAbsolutePath() + "\n" + title + " destination must be an existing directory under version control." );
  290. }
  291. }
  292. }
  293. Runner runner = new Runner();
  294. panel.addWorker( "Copy", runner );
  295. runner.execute();
  296. }
  297. }
  298. }