001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.subversion.ui.repository;
042:
043: import java.net.MalformedURLException;
044: import java.util.logging.Level;
045: import org.netbeans.modules.subversion.Subversion;
046: import org.netbeans.modules.subversion.config.Scrambler;
047: import org.netbeans.modules.subversion.util.SvnUtils;
048: import org.openide.util.NbBundle;
049: import org.tigris.subversion.svnclientadapter.SVNRevision;
050: import org.tigris.subversion.svnclientadapter.SVNUrl;
051:
052: /**
053: *
054: * @author Tomas Stupka
055: */
056: public class RepositoryConnection {
057:
058: private static final String RC_DELIMITER = "~=~";
059:
060: private String url;
061: private String username;
062: private String password;
063: private String externalCommand;
064: private boolean savePassword;
065: private SVNUrl svnUrl;
066: private SVNRevision svnRevision;
067:
068: public RepositoryConnection(RepositoryConnection rc) {
069: this (rc.url, rc.username, rc.password, rc.externalCommand,
070: rc.savePassword);
071: }
072:
073: public RepositoryConnection(String url) {
074: this (url, null, null, null, false);
075: }
076:
077: public RepositoryConnection(String url, String username,
078: String password, String externalCommand,
079: boolean savePassword) {
080: this .setUrl(url);
081: this .setUsername(username);
082: this .setPassword(password);
083: this .setExternalCommand(externalCommand);
084: this .savePassword = savePassword;
085: }
086:
087: public String getUrl() {
088: return url;
089: }
090:
091: public String getUsername() {
092: return username == null ? "" : username;
093: }
094:
095: public String getPassword() {
096: return password == null ? "" : password;
097: }
098:
099: public String getExternalCommand() {
100: return externalCommand == null ? "" : externalCommand;
101: }
102:
103: public boolean getSavePassword() {
104: return savePassword;
105: }
106:
107: public SVNUrl getSvnUrl() throws MalformedURLException {
108: if (svnUrl == null) {
109: parseUrlString(url);
110: }
111: return svnUrl;
112: }
113:
114: public SVNRevision getSvnRevision() throws MalformedURLException {
115: if (svnRevision == null) {
116: parseUrlString(url);
117: }
118: return svnRevision;
119: }
120:
121: public boolean equals(Object o) {
122: if (o == null) {
123: return false;
124: }
125: if (getClass() != o.getClass()) {
126: return false;
127: }
128:
129: final RepositoryConnection test = (RepositoryConnection) o;
130:
131: if (this .url != test.url && this .url != null
132: && !this .url.equals(test.url)) {
133: return false;
134: }
135: return true;
136: }
137:
138: public int hashCode() {
139: int hash = 3;
140: hash = 61 * hash + (this .url != null ? this .url.hashCode() : 0);
141: return hash;
142: }
143:
144: void setUrl(String url) {
145: this .url = url;
146: svnUrl = null;
147: svnRevision = null;
148: }
149:
150: void setUsername(String username) {
151: this .username = username;
152: }
153:
154: void setPassword(String password) {
155: this .password = password;
156: }
157:
158: void setExternalCommand(String externalCommand) {
159: this .externalCommand = externalCommand;
160: }
161:
162: void setSavePassword(boolean savePassword) {
163: this .savePassword = savePassword;
164: }
165:
166: public String toString() {
167: return url;
168: }
169:
170: private void parseUrlString(String urlString)
171: throws MalformedURLException {
172: int idx = urlString.lastIndexOf('@');
173: int hostIdx = urlString.indexOf("://"); // NOI18N
174: int firstSlashIdx = urlString.indexOf("/", hostIdx + 3); // NOI18N
175: if (idx < 0 || firstSlashIdx < 0 || idx < firstSlashIdx) {
176: svnRevision = SVNRevision.HEAD;
177: } else /*if (acceptRevision)*/{
178: if (idx + 1 < urlString.length()) {
179: String revisionString = ""; // NOI18N
180: try {
181: revisionString = urlString.substring(idx + 1);
182: svnRevision = SvnUtils
183: .getSVNRevision(revisionString);
184: } catch (NumberFormatException ex) {
185: throw new MalformedURLException(NbBundle
186: .getMessage(Repository.class,
187: "MSG_Repository_WrongRevision",
188: revisionString)); // NOI18N
189: }
190: } else {
191: svnRevision = SVNRevision.HEAD;
192: }
193: urlString = urlString.substring(0, idx);
194: }
195: svnUrl = removeEmptyPathSegments(new SVNUrl(urlString));
196:
197: }
198:
199: private SVNUrl removeEmptyPathSegments(SVNUrl url)
200: throws MalformedURLException {
201: String[] pathSegments = url.getPathSegments();
202: StringBuffer urlString = new StringBuffer();
203: urlString.append(url.getProtocol());
204: urlString.append("://"); // NOI18N
205: urlString.append(SvnUtils.ripUserFromHost(url.getHost()));
206: if (url.getPort() > 0) {
207: urlString.append(":"); // NOI18N
208: urlString.append(url.getPort());
209: }
210: boolean gotSegments = false;
211: for (int i = 0; i < pathSegments.length; i++) {
212: if (!pathSegments[i].trim().equals("")) { // NOI18N
213: gotSegments = true;
214: urlString.append("/"); // NOI18N
215: urlString.append(pathSegments[i]);
216: }
217: }
218: try {
219: if (gotSegments) {
220: return new SVNUrl(urlString.toString());
221: } else {
222: return url;
223: }
224: } catch (MalformedURLException ex) {
225: throw ex;
226: }
227: }
228:
229: public static String getString(RepositoryConnection rc) {
230: SVNUrl url;
231: try {
232: url = rc.getSvnUrl();
233: } catch (MalformedURLException mue) {
234: // should not happen
235: Subversion.LOG.log(Level.INFO, null, mue);
236: return ""; // NOI18N
237: }
238: StringBuffer sb = new StringBuffer();
239: sb.append(url.toString());
240: sb.append(RC_DELIMITER);
241: if (rc.getSavePassword())
242: sb.append(rc.getUsername());
243: sb.append(RC_DELIMITER);
244: if (rc.getSavePassword())
245: sb.append(Scrambler.getInstance()
246: .scramble(rc.getPassword()));
247: sb.append(RC_DELIMITER);
248: sb.append(rc.getExternalCommand());
249: sb.append(RC_DELIMITER);
250: sb.append(rc.getSavePassword());
251: sb.append(RC_DELIMITER);
252: return sb.toString();
253: }
254:
255: public static RepositoryConnection parse(String str) {
256: String[] fields = str.split(RC_DELIMITER);
257: int l = fields.length;
258: String url = fields[0];
259: String username = l > 1 && !fields[1].equals("") ? fields[1]
260: : null;
261: String password = l > 2 && !fields[2].equals("") ? Scrambler
262: .getInstance().descramble(fields[2]) : null;
263: String extCmd = l > 3 && !fields[3].equals("") ? fields[3]
264: : null;
265: boolean save = l > 4 && !fields[4].equals("") ? Boolean
266: .parseBoolean(fields[4]) : true;
267: return new RepositoryConnection(url, username, password,
268: extCmd, save);
269: }
270:
271: }
|