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 |
|
---|
52 | _mainSource = new Source("svn", info.getBaseURL() + info.getFileStem() + "/trunk/", "", this);
|
---|
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 |
|
---|
125 | ArrayList sourceElements = new ArrayList();
|
---|
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 |
|
---|
136 | Source currentSource = (Source)sourceElements.get(i);
|
---|
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 |
|
---|
149 | if(!currentSource.getFolder().equals("")){
|
---|
150 | destinationFolder = currentSource.getFolder();
|
---|
151 | }
|
---|
152 | else{
|
---|
153 | destinationFolder = defaultDownloadLocation;
|
---|
154 | }
|
---|
155 |
|
---|
156 | //Check if the directory already exists. If it does exist then as the use if they wish to delete it
|
---|
157 | File wcDir = new File(destinationFolder);
|
---|
158 | if (wcDir.exists()) {
|
---|
159 |
|
---|
160 | Object[] option = {"Continue","Cancel"};
|
---|
161 | 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",
|
---|
162 | JOptionPane.YES_NO_CANCEL_OPTION,
|
---|
163 | JOptionPane.QUESTION_MESSAGE,
|
---|
164 | null,
|
---|
165 | option,
|
---|
166 | option[0]);
|
---|
167 | if(n == 0){
|
---|
168 | ExtPane.deleteDir(wcDir);
|
---|
169 | }
|
---|
170 | else{
|
---|
171 | _button.setEnabled(true);
|
---|
172 | _button.setText(_label);
|
---|
173 | return;
|
---|
174 | }
|
---|
175 | }
|
---|
176 | wcDir.mkdirs();
|
---|
177 |
|
---|
178 | //Perform the specified checkout
|
---|
179 | String url = currentSource.getURL();
|
---|
180 | try{
|
---|
181 | SVNURL repositoryURL = SVNURL.parseURIEncoded(url);
|
---|
182 | long x = svnCheckout.doCheckout(repositoryURL, wcDir, SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, true);
|
---|
183 | }
|
---|
184 | catch(SVNException ex){
|
---|
185 | ex.printStackTrace();
|
---|
186 | _messageArea.append("Error retrieving file from SVN");
|
---|
187 | _button.setEnabled(true);
|
---|
188 | _button.setText(_label);
|
---|
189 | return;
|
---|
190 | }
|
---|
191 | }
|
---|
192 | }
|
---|
193 |
|
---|
194 | _button.setEnabled(true);
|
---|
195 | _button.setText(_label);
|
---|
196 | _parent.registerStepCompletion(DownloadStep.this);
|
---|
197 | }
|
---|
198 | }
|
---|
199 |
|
---|
200 | public class SVNCheckoutEventHandler implements ISVNEventHandler
|
---|
201 | {
|
---|
202 | public void handleEvent(SVNEvent event, double progress)
|
---|
203 | {
|
---|
204 | /*
|
---|
205 | * Gets the current action. An action is represented by SVNEventAction.
|
---|
206 | * In case of an update an action can be determined via comparing
|
---|
207 | * SVNEvent.getAction() and SVNEventAction.UPDATE_-like constants.
|
---|
208 | */
|
---|
209 |
|
---|
210 | //_messageArea.append(" event occurs");
|
---|
211 | SVNEventAction action = event.getAction();
|
---|
212 | String pathChangeType = " ";
|
---|
213 | if (action == SVNEventAction.UPDATE_ADD) {
|
---|
214 | /*
|
---|
215 | * the item was added
|
---|
216 | */
|
---|
217 | pathChangeType = "A";
|
---|
218 | } else if (action == SVNEventAction.UPDATE_DELETE) {
|
---|
219 | /*
|
---|
220 | * the item was deleted
|
---|
221 | */
|
---|
222 | pathChangeType = "D";
|
---|
223 | } else if (action == SVNEventAction.UPDATE_UPDATE) {
|
---|
224 | /*
|
---|
225 | * Find out in details what state the item is (after having been
|
---|
226 | * updated).
|
---|
227 | *
|
---|
228 | * Gets the status of file/directory item contents. It is
|
---|
229 | * SVNStatusType who contains information on the state of an item.
|
---|
230 | */
|
---|
231 | SVNStatusType contentsStatus = event.getContentsStatus();
|
---|
232 | if (contentsStatus == SVNStatusType.CHANGED) {
|
---|
233 | /*
|
---|
234 | * the item was modified in the repository (got the changes
|
---|
235 | * from the repository
|
---|
236 | */
|
---|
237 | pathChangeType = "U";
|
---|
238 | }else if (contentsStatus == SVNStatusType.CONFLICTED) {
|
---|
239 | /*
|
---|
240 | * The file item is in a state of Conflict. That is, changes
|
---|
241 | * received from the repository during an update, overlap with
|
---|
242 | * local changes the user has in his working copy.
|
---|
243 | */
|
---|
244 | pathChangeType = "C";
|
---|
245 | } else if (contentsStatus == SVNStatusType.MERGED) {
|
---|
246 | /*
|
---|
247 | * The file item was merGed (those changes that came from the
|
---|
248 | * repository did not overlap local changes and were merged
|
---|
249 | * into the file).
|
---|
250 | */
|
---|
251 | pathChangeType = "G";
|
---|
252 | }
|
---|
253 | } else if (action == SVNEventAction.UPDATE_EXTERNAL) {
|
---|
254 | /*for externals definitions*/
|
---|
255 | _messageArea.append("Fetching external item into '"
|
---|
256 | + event.getFile().getAbsolutePath() + "'");
|
---|
257 | _messageArea.append("External at revision " + event.getRevision());
|
---|
258 | return;
|
---|
259 | } else if (action == SVNEventAction.UPDATE_COMPLETED) {
|
---|
260 | /*
|
---|
261 | * Updating the working copy is completed. Prints out the revision.
|
---|
262 | */
|
---|
263 | //_messageArea.append("At revision " + event.getRevision());
|
---|
264 | _messageArea.append("At revision " + event.getRevision()+"\n");
|
---|
265 | //_messageArea.append("The extension ("+ _extensionName +") has been downloaded to the local folder: \n"+ _destination +"\n"); //xxxxx
|
---|
266 | _messageArea.setSelectionEnd(_messageArea.getDocument().getLength());
|
---|
267 | return;
|
---|
268 | } else if (action == SVNEventAction.ADD){
|
---|
269 | _messageArea.append("A " + event.getURL().getPath());
|
---|
270 | return;
|
---|
271 | } else if (action == SVNEventAction.DELETE){
|
---|
272 | _messageArea.append("D " + event.getURL().getPath());
|
---|
273 | return;
|
---|
274 | } else if (action == SVNEventAction.LOCKED){
|
---|
275 | _messageArea.append("L " + event.getURL().getPath());
|
---|
276 | return;
|
---|
277 | } else if (action == SVNEventAction.LOCK_FAILED){
|
---|
278 | _messageArea.append("failed to lock " + event.getURL().getPath());
|
---|
279 | return;
|
---|
280 | }
|
---|
281 |
|
---|
282 | /*
|
---|
283 | * Now getting the status of properties of an item. SVNStatusType also
|
---|
284 | * contains information on the properties state.
|
---|
285 | */
|
---|
286 | SVNStatusType propertiesStatus = event.getPropertiesStatus();
|
---|
287 | /*
|
---|
288 | * At first consider properties are normal (unchanged).
|
---|
289 | */
|
---|
290 | String propertiesChangeType = " ";
|
---|
291 | if (propertiesStatus == SVNStatusType.CHANGED) {
|
---|
292 | /*
|
---|
293 | * Properties were updated.
|
---|
294 | */
|
---|
295 | propertiesChangeType = "U";
|
---|
296 | } else if (propertiesStatus == SVNStatusType.CONFLICTED) {
|
---|
297 | /*
|
---|
298 | * Properties are in conflict with the repository.
|
---|
299 | */
|
---|
300 | propertiesChangeType = "C";
|
---|
301 | } else if (propertiesStatus == SVNStatusType.MERGED) {
|
---|
302 | /*
|
---|
303 | * Properties that came from the repository were merged with the
|
---|
304 | * local ones.
|
---|
305 | */
|
---|
306 | propertiesChangeType = "G";
|
---|
307 | }
|
---|
308 |
|
---|
309 | /*
|
---|
310 | * Gets the status of the lock.
|
---|
311 | */
|
---|
312 | String lockLabel = " ";
|
---|
313 | SVNStatusType lockType = event.getLockStatus();
|
---|
314 |
|
---|
315 | if (lockType == SVNStatusType.LOCK_UNLOCKED) {
|
---|
316 | /*
|
---|
317 | * The lock is broken by someone.
|
---|
318 | */
|
---|
319 | lockLabel = "B";
|
---|
320 | }
|
---|
321 |
|
---|
322 | /*
|
---|
323 | System.err.println("pathChangeType = " + pathChangeType);
|
---|
324 | System.err.println("propertiesChangeType = " + propertiesChangeType);
|
---|
325 | System.err.println("lockLabel = " + lockLabel);
|
---|
326 | System.err.println("event = " + event);
|
---|
327 | System.err.println("event.getURL = " + event.getURL());
|
---|
328 | */
|
---|
329 |
|
---|
330 | final String content = pathChangeType
|
---|
331 | + propertiesChangeType
|
---|
332 | + lockLabel
|
---|
333 | + " "
|
---|
334 | + (event.getURL() == null ? "" : event.getURL().getPath()) + "\n";
|
---|
335 |
|
---|
336 | _messageArea.append(content);
|
---|
337 | _messageArea.setSelectionEnd(_messageArea.getDocument().getLength());
|
---|
338 | }
|
---|
339 |
|
---|
340 | public void checkCancelled() throws SVNCancelException
|
---|
341 | {
|
---|
342 | }
|
---|
343 | }
|
---|
344 | } |
---|