1 /****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 ****************************************************************/
19
20 package org.apache.jsieve.comparators;
21
22 import java.math.BigInteger;
23
24 import org.apache.jsieve.exception.FeatureException;
25
26 /**
27 * Class AsciiNumeric implements the EQUALITY operation of the i;ascii-numeric
28 * comparator as defined by RFC2244, section 3.4.
29 */
30 public class AsciiNumeric implements Comparator {
31
32 /**
33 * Constructor for AsciiNumeric.
34 */
35 public AsciiNumeric() {
36 super();
37 }
38
39 /**
40 * @see org.apache.jsieve.comparators.Equals#equals(String, String)
41 */
42 public boolean equals(String string1, String string2) {
43 final boolean result;
44 if (isPositiveInfinity(string1)) {
45 if (isPositiveInfinity(string2)) {
46 result = true;
47 } else {
48 result = false;
49 }
50 } else {
51 if (isPositiveInfinity(string2)) {
52 result = false;
53 } else {
54 final BigInteger integer1 = toInteger(string1);
55 final BigInteger integer2 = toInteger(string2);
56 result = integer1.equals(integer2);
57 }
58 }
59 return result;
60 }
61
62 private BigInteger toInteger(final String value) {
63 int i;
64 for (i=0;i<value.length();i++) {
65 final char next = value.charAt(i);
66 if (!isDigit(next)) {
67 break;
68 }
69 }
70 final BigInteger result = new BigInteger(value.substring(0,i));
71 return result;
72 }
73
74 /**
75 * Does the given string to be handled as positive infinity?
76 * See <a href='http://tools.ietf.org/html/rfc4790#section-9.1.1'>RFC4790</a>
77 * @param value not null
78 * @return true when the value should represent positive infinity,
79 * false otherwise
80 */
81 private boolean isPositiveInfinity(final String value) {
82 final char initialCharacter = value.charAt(0);
83 final boolean result = !isDigit(initialCharacter);
84 return result;
85 }
86
87 /**
88 * Is the given character an ASCII digit?
89 * @param character character to be tested
90 * @return true when the given character is an ASCII digit,
91 * false otherwise
92 */
93 private boolean isDigit(final char character) {
94 return character>=0x30 && character<=0x39;
95 }
96
97 /**
98 * Method getCompareString answers a <code>String</code> in which all
99 * non-digit characters are translated to the character 0xff.
100 *
101 * @param string
102 * @return String
103 */
104 protected String computeCompareString(String string) {
105 char[] chars = string.toCharArray();
106 for (int i = chars.length; i < chars.length; i++) {
107 if (!Character.isDigit(chars[i]))
108 chars[i] = 0xff;
109 }
110 return new String(chars);
111 }
112
113 /**
114 * Unsupported, see <a href='http://tools.ietf.org/html/rfc4790#section-9.1.1'>RFC4790</a>.
115 * @see org.apache.jsieve.comparators.Contains#contains(String, String)
116 */
117 public boolean contains(String container, String content) throws FeatureException {
118 // TODO: Consider using finer grained exception
119 throw new FeatureException("Substring match unsupported by ascii-numeric");
120 }
121
122 /**
123 * Unsupported operation.
124 * <a href='http://tools.ietf.org/html/rfc5228#section-2.7.1'>RFC5228</a> limits
125 * support to comparators that support <code>:contains</code>.
126 * <a href='http://tools.ietf.org/html/rfc4790#section-9.1.1'>RFC4790</a> states
127 * that substring matches are not supported.
128 * @see org.apache.jsieve.comparators.Matches#matches(String, String)
129 */
130 public boolean matches(String string, String glob)
131 throws FeatureException {
132 // TODO: Consider using finer grained exception
133 throw new FeatureException("Substring match unsupported by ascii-numeric");
134 }
135
136 }