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.util.Vector;
016: import java.util.Enumeration;
017: import java.io.StringWriter;
018: import java.io.StreamTokenizer;
019: import java.io.IOException;
020:
021: /** A ConditionTerm represents some state configuration of a resource that must be
022: * satisfied in order for the associated request to be valid. The ConditionFactors in
023: * a ConditionTerm must all match with states of the resource, i.e., they are AND'ed
024: * together. ConditionTerms are contained in a Condition which is used in the Precondition
025: * of a WebDAV If header.
026: * @author Jim Amsden <jamsden@us.ibm.com>
027: * @see com.ibm.webdav.Precondition
028: * @see com.ibm.webdav.ConditionFactor
029: * @see com.ibm.webdav.ConditionTerm
030: * @see com.ibm.webdav.EntityTag
031: * @see com.ibm.webdav.StateToken
032: */
033: public class ConditionTerm {
034:
035: private Vector conditionFactors = new Vector();
036:
037: /** Construct a Condition with no associated Resource URI.
038: */
039: public ConditionTerm() {
040: }
041:
042: /** Add a ConditionFactor to a ConditionTerm.
043: * @param the factor to add
044: * @exception com.ibm.webdav.WebDAVException thrown if the term already contains the factor
045: */
046: public void addConditionFactor(ConditionFactor factor)
047: throws WebDAVException {
048: if (conditionFactors.contains(factor)) {
049: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
050: "Error parsing If header: duplicate entry in list");
051: }
052: conditionFactors.addElement(factor);
053: }
054:
055: /** Does this ConditionTerm contain the given ConditionFactor?
056: * @param factor the factor to check for
057: * @return true if the term contains the given factor
058: */
059: public boolean contains(ConditionFactor factor) {
060: return conditionFactors.contains(factor);
061: }
062:
063: /** Create a ConditionTerm by parsing the given If header as defined by
064: * section 9.4 in the WebDAV spec.
065: *
066: * @param tokenizer a StreamTokenizer on the contents of a WebDAV If header
067: * @return the parsed ConditionTerm
068: * @exception com.ibm.webdav.WebDAVException thrown if there is a syntax error in the If header
069: */
070: public static ConditionTerm create(StreamTokenizer tokenizer)
071: throws WebDAVException {
072: ConditionTerm term = new ConditionTerm();
073: try {
074: int token = tokenizer.ttype;
075: if (token == '(') {
076: token = tokenizer.nextToken();
077: } else {
078: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
079: "Error parsing If header: saw: " + (char) token
080: + " expected: (");
081: }
082: while (token == StreamTokenizer.TT_WORD || token == '<'
083: || token == '[') {
084: term.addConditionFactor(ConditionFactor
085: .create(tokenizer));
086: token = tokenizer.ttype;
087: }
088: if (token == ')') {
089: token = tokenizer.nextToken();
090: } else {
091: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
092: "Error parsing If header: saw: " + (char) token
093: + " expected: )");
094: }
095: } catch (IOException exc) {
096: }
097: if (!term.getConditionFactors().hasMoreElements()) {
098: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
099: "Error parsing If header: missing State-Token or entity-tag");
100: }
101: return term;
102: }
103:
104: /** Get all the ConditionFactors in this Condition. The ConditionFactors in
105: * a Condition must all match with states of the resource, i.e., they are AND'ed
106: * together. ConditionTerms are contained in a Condition which is used in the
107: * Precondition of a WebDAV If header.
108: * @return an Enumeration of ConditionFactors
109: */
110: public Enumeration getConditionFactors() {
111: return conditionFactors.elements();
112: }
113:
114: /** See if this ConditionTerm matches the given ConditionTerm. This is an
115: * AND operation. All the factors in the ConditionTerm must match.
116: * @param conditionTerm the term to match
117: * @return true if all the factors in the term match those in this term
118: */
119: public boolean matches(ConditionTerm conditionTerm) {
120: int numberOfItemsToMatch = 0;
121: boolean match = true;
122: Enumeration factors = getConditionFactors();
123: while (match && factors.hasMoreElements()) {
124: ConditionFactor factor = (ConditionFactor) factors
125: .nextElement();
126: if (factor.not()) {
127: match = !conditionTerm.contains(factor);
128: } else {
129: match = conditionTerm.contains(factor);
130: numberOfItemsToMatch++;
131: }
132: }
133: match = match
134: && numberOfItemsToMatch == conditionTerm
135: .numberOfFactors();
136: return match;
137: }
138:
139: /** Get the number of ConditionFactors in this ConditionTerm.
140: * @return the number of factors in this term
141: */
142: public int numberOfFactors() {
143: return conditionFactors.size();
144: }
145:
146: /** Return a String representation of this ConditionTerm as defined by section 9.4
147: * of the WebDAV Spec.
148: * @return a string representation of this term
149: */
150: public String toString() {
151: StringWriter os = new StringWriter();
152: os.write('(');
153: Enumeration factors = getConditionFactors();
154: while (factors.hasMoreElements()) {
155: ConditionFactor factor = (ConditionFactor) factors
156: .nextElement();
157: os.write(factor.toString());
158: if (factors.hasMoreElements()) {
159: os.write(' ');
160: }
161: }
162: os.write(')');
163: try {
164: os.close();
165: } catch (Exception exc) {
166: }
167: return os.toString();
168: }
169: }
|