001: /*
002: * ====================================================================
003: * Copyright (c) 2004-2008 TMate Software Ltd. All rights reserved.
004: *
005: * This software is licensed as described in the file COPYING, which
006: * you should have received as part of this distribution. The terms
007: * are also available at http://svnkit.com/license.html
008: * If newer versions of this license are posted there, you may use a
009: * newer version instead, at your option.
010: * ====================================================================
011: */
012:
013: package org.tmatesoft.svn.cli;
014:
015: import java.util.ArrayList;
016: import java.util.HashMap;
017: import java.util.HashSet;
018: import java.util.List;
019: import java.util.Map;
020: import java.util.Set;
021:
022: import org.tmatesoft.svn.core.SVNErrorCode;
023: import org.tmatesoft.svn.core.SVNErrorMessage;
024: import org.tmatesoft.svn.core.SVNException;
025: import org.tmatesoft.svn.core.wc.SVNRevision;
026:
027: /**
028: * @version 1.1.1
029: * @author TMate Software Ltd.
030: */
031: public class SVNCommandLine {
032:
033: private Set myUnaryArguments;
034: private Map myBinaryArguments;
035: private String myCommandName;
036: private List myPaths;
037: private List myURLs;
038: private List myPathURLs;
039: private List myPegRevisions;
040: private List myPegPathRevisions;
041:
042: public SVNCommandLine(String[] commandLine, Set validArguments)
043: throws SVNException {
044: init(commandLine, validArguments);
045: }
046:
047: public boolean hasArgument(SVNArgument argument) {
048: return myBinaryArguments.containsKey(argument)
049: || myUnaryArguments.contains(argument);
050: }
051:
052: public Object getArgumentValue(SVNArgument argument) {
053: return myBinaryArguments.get(argument);
054: }
055:
056: public void setArgumentValue(SVNArgument argument, Object value) {
057: myBinaryArguments.put(argument, value);
058: }
059:
060: public String getCommandName() {
061: return myCommandName;
062: }
063:
064: public boolean hasPaths() {
065: return !myPaths.isEmpty();
066: }
067:
068: public int getPathCount() {
069: return myPaths.size();
070: }
071:
072: public String getPathAt(int index) {
073: return (String) myPaths.get(index);
074: }
075:
076: public boolean hasURLs() {
077: return !myURLs.isEmpty();
078: }
079:
080: public int getURLCount() {
081: return myURLs.size();
082: }
083:
084: public String getURL(int index) {
085: return (String) myURLs.get(index);
086: }
087:
088: public SVNRevision getPegRevision(int index) {
089: String rev = (String) myPegRevisions.get(index);
090: return SVNRevision.parse(rev);
091: }
092:
093: public SVNRevision getPathPegRevision(int index) {
094: String rev = (String) myPegPathRevisions.get(index);
095: return SVNRevision.parse(rev);
096: }
097:
098: public void setURLAt(int index, String url) {
099: if (index >= myURLs.size()) {
100: myURLs.add(url);
101: return;
102: }
103: if (url != null) {
104: myURLs.set(index, url);
105: } else {
106: myURLs.remove(index);
107: }
108: }
109:
110: public void setPathAt(int index, String path) {
111: if (index >= myPaths.size()) {
112: myPaths.add(path);
113: myPegPathRevisions.add(SVNRevision.UNDEFINED.toString());
114: return;
115: }
116: if (path != null) {
117: myPaths.set(index, path);
118: } else {
119: myPaths.remove(index);
120: myPegPathRevisions.remove(index);
121: }
122: }
123:
124: protected void init(String[] arguments, Set validArguments)
125: throws SVNException {
126: myUnaryArguments = new HashSet();
127: myBinaryArguments = new HashMap();
128: myPaths = new ArrayList();
129: myURLs = new ArrayList();
130: myPathURLs = new ArrayList();
131: myPegRevisions = new ArrayList();
132: myPegPathRevisions = new ArrayList();
133:
134: SVNArgument previousArgument = null;
135: String previousArgumentName = null;
136: boolean hasPegRevisions = false;
137:
138: for (int i = 0; i < arguments.length; i++) {
139: String argument = arguments[i];
140: if (previousArgument != null) {
141: // parse as value (limit could allow negative numbers).
142: if (argument.startsWith("--")
143: || argument.startsWith("-")
144: && SVNArgument.LIMIT != previousArgument
145: && SVNArgument.CHANGE != previousArgument) {
146: SVNErrorMessage err = SVNErrorMessage.create(
147: SVNErrorCode.CL_ARG_PARSING_ERROR,
148: "argument '" + previousArgumentName
149: + "' requires value");
150: throw new SVNException(err);
151: }
152:
153: Object value = previousArgument.parseValue(argument);
154: myBinaryArguments.put(previousArgument, value);
155:
156: previousArgument = null;
157: previousArgumentName = null;
158: continue;
159: }
160:
161: if (argument.startsWith("--")) {
162: // long argument (--no-ignore)
163: SVNArgument svnArgument = SVNArgument.findArgument(
164: argument, validArguments);
165: if (svnArgument != null) {
166: if (svnArgument.hasValue()) {
167: previousArgument = svnArgument;
168: previousArgumentName = argument;
169: } else {
170: myUnaryArguments.add(svnArgument);
171: }
172: } else {
173: SVNErrorMessage err = SVNErrorMessage.create(
174: SVNErrorCode.CL_ARG_PARSING_ERROR,
175: "invalid argument '" + argument + "'");
176: throw new SVNException(err);
177: }
178: } else if (argument.startsWith("-")) {
179: for (int j = 1; j < argument.length(); j++) {
180: String name = "-" + argument.charAt(j);
181:
182: SVNArgument svnArgument = SVNArgument.findArgument(
183: name, validArguments);
184: if (svnArgument != null) {
185: if (svnArgument.hasValue()) {
186: if (j + 1 < argument.length()) {
187: String value = argument
188: .substring(j + 1);
189: Object argValue = svnArgument
190: .parseValue(value);
191: myBinaryArguments.put(svnArgument,
192: argValue);
193: } else {
194: previousArgument = svnArgument;
195: previousArgumentName = name;
196: }
197: j = argument.length();
198: } else {
199: myUnaryArguments.add(svnArgument);
200: }
201: } else {
202: SVNErrorMessage err = SVNErrorMessage.create(
203: SVNErrorCode.CL_ARG_PARSING_ERROR,
204: "invalid argument '" + name + "'");
205: throw new SVNException(err);
206: }
207: }
208: } else {
209:
210: if (myCommandName == null) {
211: myCommandName = argument;
212: hasPegRevisions = SVNCommand
213: .hasPegRevision(myCommandName);
214: } else {
215: String pegRevision = SVNRevision.UNDEFINED
216: .toString();
217: if (hasPegRevisions) {
218: int atIndex = argument.lastIndexOf('@');
219: if (atIndex > 0
220: && atIndex != argument.length() - 1) {
221: pegRevision = argument.substring(argument
222: .lastIndexOf('@') + 1);
223: argument = argument.substring(0, argument
224: .lastIndexOf('@'));
225: if (SVNRevision.parse(pegRevision) == SVNRevision.UNDEFINED) {
226: SVNErrorMessage msg = SVNErrorMessage
227: .create(
228: SVNErrorCode.CL_ARG_PARSING_ERROR,
229: "Syntax error parsing revision '"
230: + pegRevision
231: + "'");
232: throw new SVNException(msg);
233: }
234: } else if (atIndex > 0
235: && atIndex == argument.length() - 1) {
236: argument = argument.substring(0, argument
237: .length() - 1);
238: }
239: }
240: myPathURLs.add(argument);
241: if (argument.indexOf("://") >= 0) {
242: myURLs.add(argument);
243: myPegRevisions.add(pegRevision);
244: } else {
245: myPaths.add(argument);
246: myPegPathRevisions.add(pegRevision);
247: }
248: }
249: }
250: }
251:
252: if (myCommandName == null) {
253: SVNErrorMessage err = SVNErrorMessage.create(
254: SVNErrorCode.CL_ARG_PARSING_ERROR,
255: "no command name defined");
256: throw new SVNException(err);
257: }
258:
259: if (myPathURLs.isEmpty()) {
260: myPaths.add(".");
261: myPegPathRevisions.add(SVNRevision.UNDEFINED.toString());
262: myPathURLs.add(".");
263: }
264: }
265:
266: public boolean isURL(String url) {
267: return url != null && url.indexOf("://") >= 0;
268: }
269:
270: public boolean isPathURLBefore(String pathURL1, String pathURL2) {
271: final int index1 = myPathURLs.indexOf(pathURL1);
272: final int index2 = myPathURLs.indexOf(pathURL2);
273:
274: return index1 < index2;
275: }
276: }
|