001: package com.ibm.webdav;
002:
003: /*
004: * (C) Copyright IBM Corp. 2000 All rights reserved.
005: *
006: * The program is provided "AS IS" without any warranty express or
007: * implied, including the warranty of non-infringement and the implied
008: * warranties of merchantibility and fitness for a particular purpose.
009: * IBM will not be liable for any damages suffered by you as a result
010: * of using the Program. In no event will IBM be liable for any
011: * special, indirect or consequential damages or lost profits even if
012: * IBM has been advised of the possibility of their occurrence. IBM
013: * will not be liable for any third party claims against you.
014: */
015: import java.io.*;
016: import java.util.*;
017:
018: /** A Condition represents some state configuration of a particular resource that must be
019: * satisfied in order for the associated request to be valid. At least one of
020: * the ConditionTerms in a Condition must match with states of the resource, i.e.,
021: * they are OR'd together. Conditions are contained in a Precondition which is used in a
022: * WebDAV If header.
023: * @author Jim Amsden <jamsden@us.ibm.com>
024: * @see com.ibm.webdav.Precondition
025: * @see com.ibm.webdav.ConditionFactor
026: * @see com.ibm.webdav.ConditionTerm
027: * @see com.ibm.webdav.EntityTag
028: * @see com.ibm.webdav.StateToken
029: */
030: public class Condition {
031:
032: private String uri = null;
033: private Vector conditionTerms = new Vector();
034:
035: /** Construct a Condition on the default resource.
036: */
037: public Condition() {
038: }
039:
040: /** Construct a Condition with the given URI.
041: * @param uri the URI of the resource associated with this condition
042: */
043: public Condition(String uri) {
044: this .uri = uri;
045: }
046:
047: /** Add a ConditionTerm to a Condition.
048: * @param term the term to add
049: */
050: public void addConditionTerm(ConditionTerm term)
051: throws WebDAVException {
052: conditionTerms.addElement(term);
053: }
054:
055: /** Does this Condition contain the given ConditionTerm?
056: * @param term the term to check for
057: * @return true if the condition contains the given term, false otherwise
058: */
059: public boolean contains(ConditionTerm term) {
060: // iterate through the factors looking for a match
061: boolean match = false;
062: Enumeration terms = getConditionTerms();
063: while (!match && terms.hasMoreElements()) {
064: ConditionTerm t = (ConditionTerm) terms.nextElement();
065: match = term.matches(t);
066: }
067: return match;
068: }
069:
070: /** Create a Condition by parsing the given If header as defined by
071: * section 9.4 in the WebDAV spec.
072: *
073: * @param tokenizer a StreamTokenizer on the contents of a WebDAV If header
074: * @return the parsed condition
075: */
076: public static Condition create(StreamTokenizer tokenizer)
077: throws WebDAVException {
078: Condition condition = new Condition();
079: try {
080: int token = tokenizer.ttype;
081: if (token == '<') {
082: token = tokenizer.nextToken();
083: if (token == StreamTokenizer.TT_WORD) {
084: condition.setResourceURI(tokenizer.sval);
085: } else {
086: throw new WebDAVException(
087: WebDAVStatus.SC_BAD_REQUEST,
088: "Error parsing If header: missing resource URI");
089: }
090: token = tokenizer.nextToken();
091: if (token == '>') {
092: token = tokenizer.nextToken();
093: } else {
094: throw new WebDAVException(
095: WebDAVStatus.SC_BAD_REQUEST,
096: "Error parsing If header: saw: "
097: + (char) token + " expected: >");
098: }
099: }
100: if (token == '(') {
101: while (token == '(') {
102: condition.addConditionTerm(ConditionTerm
103: .create(tokenizer));
104: token = tokenizer.ttype;
105: }
106: } else {
107: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
108: "Error parsing If header: saw: " + (char) token
109: + " expected: ( or <");
110: }
111: } catch (IOException exc) {
112: }
113: return condition;
114: }
115:
116: /** Create a Condition by parsing the given If header as defined by
117: * section 9.4 in the WebDAV spec.
118: *
119: * @param ifHeader the contents of a WebDAV If header
120: * @return the parsed condition
121: * @exception com.ibm.webdav.WebDAVException thrown if there is a syntax error in the header
122: */
123: public static Condition create(String ifHeader)
124: throws WebDAVException {
125: StreamTokenizer tokenizer = new StreamTokenizer(
126: new StringReader(ifHeader));
127: // URI characters
128: tokenizer.wordChars('!', '/');
129: tokenizer.wordChars(':', '@');
130: tokenizer.ordinaryChar('(');
131: tokenizer.ordinaryChar(')');
132: tokenizer.ordinaryChar('<');
133: tokenizer.ordinaryChar('>');
134: tokenizer.ordinaryChar('[');
135: tokenizer.ordinaryChar(']');
136: tokenizer.quoteChar('"');
137: Condition condition = null;
138: try {
139: int token = tokenizer.nextToken();
140: condition = Condition.create(tokenizer);
141: token = tokenizer.ttype;
142: if (token != StreamTokenizer.TT_EOF) {
143: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
144: "Error parsing If header: saw: " + (char) token
145: + " expected: EOF");
146: }
147: } catch (IOException exc) {
148: }
149: return condition;
150: }
151:
152: /** Get all the ConditionTerms for this Condition. At least one of the ConditionTerms in
153: * a Condition must match with states of the resource, i.e., they are OR'd
154: * together. Conditions are contained in a Precondition which is used in a
155: * WebDAV If header.
156: */
157: public Enumeration getConditionTerms() {
158: return conditionTerms.elements();
159: }
160:
161: /** Get the URI of the associated Resource. The condition must match on this
162: * resource. This is useful for Preconditions that span multiple resources.
163: * @return the resource URI whose state is described by this Condition, may be null
164: * indicating the condition applies to the resource receiving the request
165: */
166: public String getResourceURI() {
167: return uri;
168: }
169:
170: /** See if this Condition matches the given Condition. This is an
171: * OR operation.
172: * @param condition the condition to match against
173: * @return true if the conditions match, false otherwise.
174: */
175: public boolean matches(Condition condition) {
176: // check the Resource if one was given
177: boolean match = true;
178: if (uri != null) {
179: try {
180: /* Don't match on the protocol, host, and port, they don't really matter.
181: * If we're here on this server, then the client must have provided
182: * a protocol, host, and port that gets to a resource this server manages.
183: * So we shouldn't interpret these URIs as URLs, but rather as opaque
184: * strings that identify the resource on this server
185: */
186: /*
187: URL url1 = new URL(uri);
188: URL url2 = new URL(condition.getResourceURI());
189: match = match && url1.getProtocol().equals(url2.getProtocol());
190: match = match && url1.getHost().equals(url2.getHost());
191: int port1 = url1.getPort();
192: if (port1 == -1) { // use the default port
193: port1 = 80;
194: }
195: int port2 = url2.getPort();
196: if (port2 == -1) {
197: port2 = 80;
198: }
199: match = match && (port1 == port2);
200: match = match && url1.getFile().equals(url2.getFile());
201: */
202: match = uri.equals(condition.getResourceURI());
203: } catch (Exception exc) {
204: match = false;
205: }
206: }
207: if (!match) {
208: return false;
209: }
210: // is each term in the condition in the given condition
211: match = false;
212: Enumeration terms = getConditionTerms();
213: while (!match && terms.hasMoreElements()) {
214: ConditionTerm term = (ConditionTerm) terms.nextElement();
215: match = condition.contains(term);
216: }
217: return match;
218: }
219:
220: /** Set the URI of the associated Resource. The condition must match on this
221: * resource. This is useful for Preconditions that span multiple resources.
222: * @param value the resource URI whose state is described by this Condition.
223: * value can be null if the condition applies to the resource executing
224: * the method.
225: */
226: public void setResourceURI(String value) {
227: uri = value;
228: }
229:
230: /** Return a String representation of this Condition as defined by section 9.4
231: * of the WebDAV Spec.
232: * @return a String representation of this condition
233: */
234: public String toString() {
235: StringWriter os = new StringWriter();
236: if (getResourceURI() != null) {
237: os.write('<');
238: os.write(getResourceURI());
239: os.write("> ");
240: }
241: Enumeration terms = getConditionTerms();
242: while (terms.hasMoreElements()) {
243: ConditionTerm term = (ConditionTerm) terms.nextElement();
244: os.write(term.toString());
245: if (terms.hasMoreElements()) {
246: os.write(' ');
247: }
248: }
249: try {
250: os.close();
251: } catch (Exception exc) {
252: }
253: return os.toString();
254: }
255: }
|