1 /*
2 * Copyright 2002, Aegeus Technology Limited.
3 * All rights reserved.
4 */
5 package jsdsi;
6
7 import java.util.Iterator;
8
9 import jsdsi.sexp.Sexp;
10 import jsdsi.sexp.SexpParseException;
11 import jsdsi.sexp.SexpUtil;
12
13 /***
14 * A tag that matches strings that prefix its own string value, i.e.
15 * (tag (* reverse-prefix /my/private)) implies (tag /my) but not (tag
16 * /my/private/file)
17 *
18 * @author Sean Radford
19 * @version $Revision: 1.5 $ $Date: 2004/11/08 12:08:08 $
20 *
21 */
22 public class ReversePrefixTag extends ExprTag {
23
24 private static final long serialVersionUID = -1771391400337244600L;
25
26 /***
27 * The value
28 */
29 private transient final String value;
30
31 /***
32 * Creates a new <code>ReversePrefixTag</code> with a given prefix string.
33 *
34 * @param value the string to match against.
35 */
36 public ReversePrefixTag(String value) {
37 assert(value != null) : "null value";
38 this.value = value;
39 }
40
41 /***
42 * @see jsdsi.Tag#intersect(Tag)
43 */
44 public Tag intersect(Tag that)
45 {
46 if (that instanceof ReversePrefixTag) {
47 return intersect((ReversePrefixTag)that);
48 }
49 if (that instanceof PrefixTag) {
50 return intersect((PrefixTag)that);
51 }
52 if (that instanceof StringTag) {
53 return intersect((StringTag)that);
54 }
55 if (that instanceof SetTag) {
56 return that.intersect(this);
57 }
58 return Tag.NULL_TAG;
59 }
60
61 /***
62 * @see jsdsi.Tag#intersect(Tag)
63 */
64 public Tag intersect(ReversePrefixTag that)
65 {
66 if (this.value.startsWith(that.value)) {
67 return that;
68 }
69 if (that.value.startsWith(this.value)) {
70 return this;
71 }
72 return Tag.NULL_TAG;
73 }
74
75 /***
76 * @see jsdsi.Tag#intersect(Tag)
77 */
78 public Tag intersect(PrefixTag that)
79 {
80 if (this.value.startsWith(that.getPrefix())==false) {
81 return Tag.NULL_TAG;
82 }
83 int diff = indexOfDifference(value, that.getPrefix());
84 if (diff==-1) {
85 // values are equals
86 return new StringTag(value);
87 }
88 // ReversePrefix startswith Prefix, so need a Set of Strings
89 // from Prefix to ReversePrefix (* reverse-prefix /my/pub)
90 // intersect (* prefix /my) is (* set /my /my/ /my/p /my/pu
91 // /my/pub)
92 int num = value.length() - diff +1; // number in Set
93 ExprTag[] eTags = new ExprTag[num];
94 for (int index = 0; index<num; index++) {
95 eTags[index] = new StringTag(value.substring(0, diff + index));
96 }
97 return new SetTag( eTags );
98 }
99
100 /***
101 * Compares two Strings, and returns the index at which the Strings
102 * begin to differ.
103 *
104 * @param str1
105 * @param str2
106 * @return the index where str2 and str1 begin to differ; -1 if they
107 * are equal
108 */
109 private static int indexOfDifference(String str1, String str2) {
110 if (str1 == str2) {
111 return -1;
112 }
113 if (str1 == null || str2 == null) {
114 return 0;
115 }
116 int i;
117 for (i = 0; i < str1.length() && i < str2.length(); ++i) {
118 if (str1.charAt(i) != str2.charAt(i)) {
119 break;
120 }
121 }
122 if (i < str2.length() || i < str1.length()) {
123 return i;
124 }
125 return -1;
126 }
127
128
129 /***
130 * @see jsdsi.Tag#intersect(Tag)
131 */
132 public Tag intersect(StringTag that)
133 {
134 if (this.value.startsWith(that.getValue())) {
135 return that;
136 }
137 return Tag.NULL_TAG;
138 }
139
140 /***
141 * @see java.lang.Object#equals(Object)
142 */
143 public boolean equals(Object that) {
144 return (that instanceof ReversePrefixTag)
145 && this.value.equals(((ReversePrefixTag) that).value);
146 }
147
148 /***
149 * @see java.lang.Object#hashCode()
150 */
151 public int hashCode() {
152 return value.hashCode();
153 }
154
155 /***
156 * @return the value of this tag.
157 */
158 public String getValue() {
159 return value;
160 }
161
162 public Sexp toTagSexp() {
163 Sexp[] ss = new Sexp[2];
164 ss[0] = SexpUtil.toSexp("reverse-prefix");
165 ss[1] = SexpUtil.toSexp(getValue());
166 return SexpUtil.toSexp("*", ss);
167 }
168
169 static ReversePrefixTag parseReversePrefixTag(Iterator tbody)
170 throws SexpParseException {
171 String p = SexpUtil.getNextString(tbody, "reverse-prefix tag");
172 SexpUtil.checkDone(tbody, "reverse-prefix tag");
173 return new ReversePrefixTag(p);
174 }
175 }
This page was automatically generated by Maven