Add missing NetBeans *.form files.
[nbgit.git] / src / org / netbeans / modules / git / ui / wizards / CloneRepositoryWizardPanel.java
blobdf6368a4ccd5a35c5ddc201692a3b71acff7b7ed
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common
8 * Development and Distribution License("CDDL") (collectively, the
9 * "License"). You may not use this file except in compliance with the
10 * License. You can obtain a copy of the License at
11 * http://www.netbeans.org/cddl-gplv2.html
12 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13 * specific language governing permissions and limitations under the
14 * License. When distributing the software, include this License Header
15 * Notice in each file and include the License file at
16 * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17 * particular file as subject to the "Classpath" exception as provided
18 * by Sun in the GPL Version 2 section of the License file that
19 * accompanied this code. If applicable, add the following below the
20 * License Header, with the fields enclosed by brackets [] replaced by
21 * your own identifying information:
22 * "Portions Copyrighted [year] [name of copyright owner]"
24 * Contributor(s):
26 * The Original Software is NetBeans. The Initial Developer of the Original
27 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28 * Microsystems, Inc. All Rights Reserved.
29 * Portions Copyright 2008 Alexander Coles (Ikonoklastik Productions).
31 * If you wish your version of this file to be governed by only the CDDL
32 * or only the GPL Version 2, indicate your decision by adding
33 * "[Contributor] elects to include this software in this distribution
34 * under the [CDDL or GPL Version 2] license." If you do not indicate a
35 * single choice of license, a recipient has the option to distribute
36 * your version of this file under either the CDDL, the GPL Version 2 or
37 * to extend the choice of license to its licensees as provided above.
38 * However, if you add GPL Version 2 code and therefore, elected the GPL
39 * Version 2 license, then the option applies only if the new code is
40 * made subject to such option by the copyright holder.
42 package org.netbeans.modules.git.ui.wizards;
44 import java.awt.BorderLayout;
45 import java.awt.Component;
46 import java.beans.PropertyChangeEvent;
47 import java.beans.PropertyChangeListener;
48 import java.io.File;
49 import java.io.IOException;
50 import java.net.HttpURLConnection;
51 import java.net.URI;
52 import java.net.URISyntaxException;
53 import java.net.URL;
54 import java.util.HashSet;
55 import java.util.Iterator;
56 import java.util.Set;
57 import java.util.logging.Level;
58 import javax.swing.JPanel;
59 import javax.swing.event.ChangeEvent;
60 import javax.swing.event.ChangeListener;
61 import org.netbeans.modules.git.Git;
62 import org.netbeans.modules.git.GitModuleConfig;
63 import org.netbeans.modules.git.ui.repository.Repository;
64 import org.netbeans.modules.git.ui.repository.RepositoryConnection;
65 import org.openide.WizardDescriptor;
66 import org.openide.WizardValidationException;
67 import org.openide.util.HelpCtx;
68 import org.openide.util.NbBundle;
69 import org.openide.util.RequestProcessor;
71 public class CloneRepositoryWizardPanel implements WizardDescriptor.AsynchronousValidatingPanel, PropertyChangeListener {
73 /**
74 * The visual component that displays this panel. If you need to access the
75 * component from this class, just use getComponent().
77 private CloneRepositoryPanel component;
78 private Repository repository;
79 private int repositoryModeMask;
80 private boolean valid;
81 private String errorMessage;
82 private WizardStepProgressSupport support;
84 // Get the visual component for the panel. In this template, the component
85 // is kept separate. This can be more efficient: if the wizard is created
86 // but never displayed, or not all panels are displayed, it is better to
87 // create only those which really need to be visible.
88 public Component getComponent() {
89 if (component == null) {
90 component = new CloneRepositoryPanel();
91 if (repository == null) {
92 repositoryModeMask = repositoryModeMask | Repository.FLAG_URL_EDITABLE | Repository.FLAG_URL_ENABLED | Repository.FLAG_SHOW_HINTS | Repository.FLAG_SHOW_PROXY;
93 String title = org.openide.util.NbBundle.getMessage(CloneRepositoryWizardPanel.class, "CTL_Repository_Location"); // NOI18N
94 repository = new Repository(repositoryModeMask, title);
95 repository.addPropertyChangeListener(this);
96 CloneRepositoryPanel panel = (CloneRepositoryPanel)component;
97 panel.repositoryPanel.setLayout(new BorderLayout());
98 panel.repositoryPanel.add(repository.getPanel());
99 valid();
102 return component;
105 public HelpCtx getHelp() {
106 return new HelpCtx(CloneRepositoryWizardPanel.class);
109 //public boolean isValid() {
110 // If it is always OK to press Next or Finish, then:
111 // return true;
112 // If it depends on some condition (form filled out...), then:
113 // return someCondition();
114 // and when this condition changes (last form field filled in...) then:
115 // fireChangeEvent();
116 // and uncomment the complicated stuff below.
119 public void propertyChange(PropertyChangeEvent evt) {
120 if(evt.getPropertyName().equals(Repository.PROP_VALID)) {
121 if(repository.isValid()) {
122 valid(repository.getMessage());
123 } else {
124 invalid(repository.getMessage());
129 private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
130 public final void addChangeListener(ChangeListener l) {
131 synchronized (listeners) {
132 listeners.add(l);
135 public final void removeChangeListener(ChangeListener l) {
136 synchronized (listeners) {
137 listeners.remove(l);
140 protected final void fireChangeEvent() {
141 Iterator<ChangeListener> it;
142 synchronized (listeners) {
143 it = new HashSet<ChangeListener>(listeners).iterator();
145 ChangeEvent ev = new ChangeEvent(this);
146 while (it.hasNext()) {
147 it.next().stateChanged(ev);
151 protected final void valid() {
152 setValid(true, null);
155 protected final void valid(String extErrorMessage) {
156 setValid(true, extErrorMessage);
159 protected final void invalid(String message) {
160 setValid(false, message);
163 public final boolean isValid() {
164 return valid;
167 public final String getErrorMessage() {
168 return errorMessage;
171 private void setValid(boolean valid, String errorMessage) {
172 boolean fire = this.valid != valid;
173 fire |= errorMessage != null && (errorMessage.equals(this.errorMessage) == false);
174 this.valid = valid;
175 this.errorMessage = errorMessage;
176 if (fire) {
177 fireChangeEvent();
181 protected void validateBeforeNext() {
182 try {
183 support = new RepositoryStepProgressSupport(component.progressPanel);
185 String url = getUrl();
186 support.setRepositoryRoot(url);
187 RequestProcessor rp = Git.getInstance().getRequestProcessor(url);
188 RequestProcessor.Task task = support.start(rp, url, NbBundle.getMessage(CloneRepositoryWizardPanel.class, "BK2012"));
189 task.waitFinished();
190 } finally {
191 support = null;
196 // comes on next or finish
197 public final void validate () throws WizardValidationException {
198 validateBeforeNext();
199 if (isValid() == false || errorMessage != null) {
200 throw new WizardValidationException (
201 (javax.swing.JComponent) component,
202 errorMessage,
203 errorMessage
208 // You can use a settings object to keep track of state. Normally the
209 // settings object will be the WizardDescriptor, so you can use
210 // WizardDescriptor.getProperty & putProperty to store information entered
211 // by the user.
212 public void readSettings(Object settings) {}
213 public void storeSettings(Object settings) {
214 if (settings instanceof WizardDescriptor) {
215 ((WizardDescriptor) settings).putProperty("repository", repository.getSelectedRC().getUrl()); // NOI18N
216 ((WizardDescriptor) settings).putProperty("username", repository.getSelectedRC().getUsername()); // NOI18N
217 ((WizardDescriptor) settings).putProperty("password", repository.getSelectedRC().getPassword()); // NOI18N
221 public void prepareValidation() {
224 private String getUrl() {
225 return getSelectedRepositoryConnection().getUrl();
228 private void storeHistory() {
229 RepositoryConnection rc = getSelectedRepositoryConnection();
230 if(rc != null) {
231 GitModuleConfig.getDefault().insertRecentUrl(rc);
235 private RepositoryConnection getSelectedRepositoryConnection() {
236 try {
237 return repository.getSelectedRC();
238 } catch (Exception ex) {
239 invalid(ex.getLocalizedMessage());
240 return null;
244 public void stop() {
245 if(support != null) {
246 support.cancel();
250 private class RepositoryStepProgressSupport extends WizardStepProgressSupport {
252 public RepositoryStepProgressSupport(JPanel panel) {
253 super(panel);
256 public void perform() {
257 final RepositoryConnection rc = getSelectedRepositoryConnection();
258 if (rc == null) {
259 return;
261 String invalidMsg = null;
262 try {
263 invalid(null);
265 // This command validates the url
266 rc.getHgUrl();
267 String urlStr = rc.getUrl();
268 URI uri = new URI(urlStr);
269 String uriSch = uri.getScheme();
270 if(uriSch.equals("file")){
271 File f = new File(urlStr.substring("file://".length()));
272 if(!f.exists() || !f.canRead()){
273 invalidMsg = NbBundle.getMessage(CloneRepositoryWizardPanel.class,
274 "MSG_Progress_Clone_CannotAccess_Err");
275 return;
277 }else if(uriSch.equals("http") || uriSch.equals("https")) {
278 URL url = new URL(urlStr);
279 HttpURLConnection con = (HttpURLConnection) url.openConnection();
280 // Note: valid repository returns con.getContentLength() = -1
281 // so no way to reliably test if this url exists, without using hg
282 if (con != null){
283 String userInfo = uri.getUserInfo();
284 boolean bNoUserAndOrPasswordInURL = userInfo == null;
285 // If username or username:password is in the URL the con.getResponseCode() returns -1 and this check would fail
286 if (bNoUserAndOrPasswordInURL && con.getResponseCode() != HttpURLConnection.HTTP_OK){
287 invalidMsg = NbBundle.getMessage(CloneRepositoryWizardPanel.class,
288 "MSG_Progress_Clone_CannotAccess_Err");
289 con.disconnect();
290 return;
291 }else if (userInfo != null){
292 Git.LOG.log(Level.FINE,
293 "RepositoryStepProgressSupport.perform(): UserInfo - {0}", new Object[]{userInfo}); // NOI18N
295 con.disconnect();
298 } catch (java.lang.IllegalArgumentException ex) {
299 invalidMsg = NbBundle.getMessage(CloneRepositoryWizardPanel.class,
300 "MSG_Progress_Clone_InvalidURL_Err");
301 return;
302 } catch (IOException ex) {
303 invalidMsg = NbBundle.getMessage(CloneRepositoryWizardPanel.class,
304 "MSG_Progress_Clone_CannotAccess_Err");
305 return;
306 } catch (URISyntaxException ex) {
307 invalidMsg = NbBundle.getMessage(CloneRepositoryWizardPanel.class,
308 "MSG_Progress_Clone_InvalidURL_Err");
309 return;
310 } finally {
311 if(isCanceled()) {
312 valid(org.openide.util.NbBundle.getMessage(CloneRepositoryWizardPanel.class, "CTL_Repository_Canceled")); // NOI18N
313 } else if(invalidMsg == null) {
314 valid();
315 storeHistory();
316 } else {
317 invalid(invalidMsg);
322 public void setEditable(boolean editable) {
323 repository.setEditable(editable);