001: /*
002: ** Java cvs client library package.
003: ** Copyright (c) 1997-2002 by Timothy Gerard Endres
004: **
005: ** This program is free software.
006: **
007: ** You may redistribute it and/or modify it under the terms of the GNU
008: ** Library General Public License (LGPL) as published by the Free Software
009: ** Foundation.
010: **
011: ** Version 2 of the license should be included with this distribution in
012: ** the file LICENSE.txt, as well as License.html. If the license is not
013: ** included with this distribution, you may find a copy at the FSF web
014: ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the Free
015: ** Software Foundation at 59 Temple Place - Suite 330, Boston, MA 02111 USA.
016: **
017: ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
018: ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
019: ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
020: ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
021: ** REDISTRIBUTION OF THIS SOFTWARE.
022: **
023: */
024:
025: package com.ice.cvsc;
026:
027: import java.io.*;
028: import java.lang.*;
029: import java.text.*;
030: import java.util.*;
031:
032: /**
033: * CVSEntry implements the concept of a CVS Entry. Traditionally,
034: * a CVS Entry is a line in an 'Entries' file in a 'CVS' admin
035: * directory. A CVSEntry represents a CVS file that is checked
036: * in or being checked in.
037: *
038: * CVSEntry objects contain all of the relavent information about
039: * a CVS file, such as its name, check-out time, modification status,
040: * local pathname, repository, etc.
041: *
042: * @version $Revision: 2.4 $
043: * @author Timothy Gerard Endres, <a href="mailto:time@ice.com">time@ice.com</a>.
044: * @see CVSClient
045: * @see CVSProject
046: * @see CVSEntryVector
047: */
048:
049: public class CVSProjectDef extends Object {
050: static public final String RCS_ID = "$Id: CVSProjectDef.java,v 2.4 2003/07/27 01:08:32 time Exp $";
051: static public final String RCS_REV = "$Revision: 2.4 $";
052:
053: /**
054: * True if this definition is parsed and valid.
055: */
056: private boolean isValid;
057:
058: /**
059: * True if this used a password INETD login method.
060: */
061: private boolean isPServer;
062:
063: /**
064: * The connection method.
065: */
066: private int connectMethod;
067: private String connectMethodStr;
068:
069: /**
070: * The CVS server hostname.
071: */
072: private String hostName;
073:
074: /**
075: * The user name used for login.
076: */
077: private String userName;
078:
079: /**
080: * The CVS root directory.
081: */
082: private String rootDirectory;
083:
084: /**
085: * The CVS repository path.
086: */
087: private String repository;
088:
089: /**
090: * The reason we are not valid.
091: */
092: private String reason;
093:
094: /**
095: * Set to true when we see a Root spec with no "method",
096: * such as "user@host:/path/to/cvs".
097: */
098: private boolean noModeRoot;
099:
100: public CVSProjectDef(String rootStr, String reposStr) {
101: this .parseRootDirectory(rootStr, reposStr);
102: }
103:
104: public CVSProjectDef(int connMeth, boolean isPServ, boolean noMode,
105: String host, String user, String rootDir, String repos) {
106: this .isValid = true; // UNDONE
107: this .isPServer = isPServ;
108: this .noModeRoot = noMode;
109:
110: this .hostName = host;
111: this .userName = user;
112: this .repository = repos;
113: this .rootDirectory = rootDir;
114:
115: this .connectMethod = connMeth;
116:
117: if (this .connectMethod == CVSRequest.METHOD_RSH) {
118: this .connectMethodStr = "server";
119: } else if (this .connectMethod == CVSRequest.METHOD_SSH) {
120: this .connectMethodStr = "ext";
121: } else if (this .isPServer) {
122: this .connectMethodStr = "pserver";
123: } else {
124: this .connectMethodStr = "direct";
125: }
126: }
127:
128: public synchronized boolean isValid() {
129: return this .isValid;
130: }
131:
132: public synchronized boolean isPServer() {
133: return this .isPServer;
134: }
135:
136: public synchronized boolean isSSHServer() {
137: return (this .connectMethod == CVSRequest.METHOD_SSH);
138: }
139:
140: public synchronized int getConnectMethod() {
141: return this .connectMethod;
142: }
143:
144: public synchronized String getConnectMethodString() {
145: return this .connectMethodStr;
146: }
147:
148: public synchronized String getUserName() {
149: return this .userName;
150: }
151:
152: public synchronized String getHostName() {
153: return this .hostName;
154: }
155:
156: public synchronized String getRootDirectory() {
157: return this .rootDirectory;
158: }
159:
160: public synchronized String getRepository() {
161: return this .repository;
162: }
163:
164: public synchronized String getReason() {
165: return this .reason;
166: }
167:
168: public String getRootDirectorySpec() {
169: String connMethod;
170:
171: if (this .connectMethod == CVSRequest.METHOD_RSH) {
172: connMethod = "server";
173: } else if (this .connectMethod == CVSRequest.METHOD_SSH) {
174: connMethod = "ext";
175: } else if (this .isPServer()) {
176: connMethod = "pserver";
177: } else {
178: connMethod = "direct";
179: }
180:
181: StringBuffer rootDirStr = new StringBuffer(128);
182:
183: if (!this .noModeRoot) {
184: rootDirStr.append(":");
185: rootDirStr.append(connMethod);
186: rootDirStr.append(":");
187: }
188:
189: if (this .userName.length() > 0) {
190: rootDirStr.append(this .userName);
191: rootDirStr.append("@");
192: }
193:
194: rootDirStr.append(this .hostName);
195:
196: /*
197: ** UNDONE HIGH
198: ** Standard CVS URL has a port field:
199: **
200: // If there is a non-standard port, add to URL
201: if ( this.isPServer() )
202: {
203: if ( this.port != CVSClient.DEFAULT_CVS_PORT )
204: {
205: rootDirStr.append( "#" );
206: rootDirStr.append( this.port );
207: }
208: }
209: **
210: */
211:
212: rootDirStr.append(":");
213: rootDirStr.append(this .rootDirectory);
214:
215: return rootDirStr.toString();
216: }
217:
218: public synchronized boolean parseRootDirectory(
219: String specification, String repos) {
220: String tempStr;
221: String methodStr;
222: String userNameStr = "";
223: String hostNameStr = "";
224: int index, subidx;
225: int connMethod;
226: boolean isOk = true;
227:
228: this .isValid = false;
229: this .isPServer = false;
230: this .repository = repos;
231: this .noModeRoot = false;
232:
233: this .reason = "parsed '" + specification + "'";
234:
235: String rootDirSpec = specification;
236:
237: if (rootDirSpec.startsWith(":")) {
238: rootDirSpec = rootDirSpec.substring(1);
239:
240: index = rootDirSpec.indexOf(':');
241: if (index > 0) {
242: methodStr = rootDirSpec.substring(0, index);
243: rootDirSpec = rootDirSpec.substring(index + 1);
244:
245: if (methodStr.equalsIgnoreCase("ext")
246: || methodStr.equalsIgnoreCase("pserver")
247: || methodStr.equalsIgnoreCase("direct")
248: || methodStr.equalsIgnoreCase("server")) {
249: this .connectMethodStr = methodStr;
250:
251: index = rootDirSpec.indexOf(':');
252: tempStr = rootDirSpec.substring(0, index);
253:
254: this .rootDirectory = rootDirSpec
255: .substring(index + 1);
256:
257: if (index > 0) {
258: if (methodStr.equals("pserver")) {
259: this .isPServer = true;
260: this .connectMethod = CVSRequest.METHOD_INETD;
261: } else if (methodStr.equals("server")) {
262: this .isPServer = false;
263: this .connectMethod = CVSRequest.METHOD_RSH;
264: } else if (methodStr.equals("ext")) {
265: this .isPServer = false;
266: this .connectMethod = CVSRequest.METHOD_SSH;
267: } else if (methodStr.equals("direct")) {
268: this .isPServer = false;
269: this .connectMethod = CVSRequest.METHOD_INETD;
270: } else {
271: this .isPServer = false;
272: this .connectMethod = CVSRequest.METHOD_RSH;
273: }
274:
275: subidx = tempStr.indexOf('@');
276: if (subidx > 0) {
277: // ':method:user@host:...' format
278: this .userName = tempStr
279: .substring(0, subidx);
280: this .hostName = tempStr
281: .substring(subidx + 1);
282: } else {
283: // ':method:host:...' format
284: this .userName = System.getProperty(
285: "user.name", "");
286: this .hostName = tempStr;
287: if (this .isPServer) {
288: isOk = false;
289: CVSLog
290: .logMsg("ERROR Root directory spec '"
291: + specification
292: + "' is invalid (pserver: no user).");
293: }
294: }
295: } else {
296: isOk = false;
297: this .reason = "ERROR Root directory spec '"
298: + specification
299: + "' is invalid (incomplete).";
300: }
301: } else {
302: isOk = false;
303: this .reason = "ERROR Root directory spec '"
304: + specification
305: + "' is invalid (server not 'server' or 'pserver').";
306: }
307: } else {
308: isOk = false;
309: this .reason = "ERROR Root directory spec '"
310: + specification
311: + "' is invalid (no server spec).";
312: }
313:
314: this .isValid = isOk;
315: } else {
316: // The command line client sometimes uses an "empty method" with
317: // a "user@host:path" syntax that implies the "server" method.
318: //
319: index = rootDirSpec.indexOf('@');
320: subidx = rootDirSpec.indexOf(':');
321:
322: if (index > 0 && subidx > index) {
323: this .isValid = true;
324: this .noModeRoot = true;
325: this .isPServer = false;
326: this .connectMethod = CVSRequest.METHOD_RSH;
327: this .connectMethodStr = "";
328: this .userName = rootDirSpec.substring(0, index);
329: this .hostName = rootDirSpec
330: .substring(index + 1, subidx);
331: this .rootDirectory = rootDirSpec.substring(subidx + 1);
332: } else {
333: this .isValid = false;
334: this .reason = "ERROR Root directory spec '"
335: + specification + "' is invalid.";
336: }
337: }
338:
339: if (this .isValid
340: && !this .repository.startsWith(this .rootDirectory)) {
341: this .repository = this .rootDirectory + "/"
342: + this .repository;
343: }
344:
345: return this .isValid;
346: }
347:
348: /**
349: * @param adminPath The path to the 'CVS/' admin directory.
350: */
351: public static CVSProjectDef readDef(String adminPath)
352: throws IOException {
353: String rootPath = CVSProject.getAdminRootPath(adminPath);
354:
355: File adminRootFile = new File(rootPath);
356:
357: if (!adminRootFile.exists())
358: throw new IOException("admin Root file '"
359: + adminRootFile.getPath() + "' does not exist");
360:
361: String reposPath = CVSProject.getAdminRepositoryPath(adminPath);
362:
363: File adminReposFile = new File(reposPath);
364:
365: if (!adminReposFile.exists())
366: throw new IOException("admin Repository file '"
367: + adminReposFile.getPath() + "' does not exist");
368:
369: String rootDirectoryStr = CVSCUtilities
370: .readStringFile(adminRootFile);
371:
372: if (rootDirectoryStr == null)
373: throw new IOException("reading admin Root file '"
374: + adminRootFile.getPath());
375:
376: String repositoryStr = CVSCUtilities
377: .readStringFile(adminReposFile);
378:
379: if (repositoryStr == null)
380: throw new IOException("reading admin Repository file '"
381: + adminReposFile.getPath());
382:
383: CVSProjectDef def = new CVSProjectDef(rootDirectoryStr,
384: repositoryStr);
385:
386: if (!def.isValid()) {
387: throw new IOException("CVS admin defintion is not valid, "
388: + def.getReason());
389: }
390:
391: return def;
392: }
393:
394: }
|