1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.archive.crawler.settings;
26
27 import java.io.Serializable;
28 import java.text.MessageFormat;
29 import java.util.ArrayList;
30 import java.util.logging.Level;
31
32
33 /***
34 * Superclass for constraints that can be set on attribute definitions.
35 * <p>
36 * Constraints will be checked against attribute values. If a constraint check
37 * fails, an object of type FailedCheck is returned containing information that
38 * can be used to build meaningful information to the user.
39 * <p>
40 * A constraint has one of three levels:
41 * <ul>
42 * <li>{@link java.util.logging.Level#SEVERE}The attribute could not be set
43 * whatsoever.
44 * <li>{@link java.util.logging.Level#WARNING}The attribute is illegal i
45 * CrawlJobs, but could be set in profiles. Mostly used as holder value for
46 * settings that should be changed for every entity running a crawl.
47 * <li>{@link java.util.logging.Level#INFO}The attribute has a legal value,
48 * but is outside the bounds of what are considered a reasonable value. The user
49 * could be warned that she should investigate if the value actally is what she
50 * wants it be.
51 * </ul>
52 *
53 * @author John Erik Halse
54 */
55 public abstract class Constraint
56 implements Comparable<Constraint>, Serializable {
57 static final long serialVersionUID = -646814290764700497L;
58
59 private final Level severity;
60 private final String msg;
61
62 /*** Constructs a new Constraint.
63 *
64 * @param level the level for this constraint.
65 * @param msg default message to return if the check fails.
66 */
67 public Constraint(Level level, String msg) {
68 if (level != Level.SEVERE && level != Level.WARNING
69 && level != Level.INFO) {
70 throw new IllegalArgumentException("Illegal level: "
71 + level.getName());
72 }
73 this.severity = level;
74 this.msg = msg;
75 }
76
77 /***
78 * Run the check.
79 *
80 * @param owner the ComplexType owning the attribute to check.
81 * @param definition the definition to check the attribute against.
82 * @param value the value to check.
83 * @return null if ok, or an instance of {@link FailedCheck}if the check
84 * failed.
85 */
86 public final FailedCheck check(CrawlerSettings settings, ComplexType owner,
87 Type definition, Object value) {
88 return innerCheck(settings, owner, definition, value);
89 }
90
91 /*** The method all subclasses should implement to do the actual checking.
92 *
93 * @param owner the ComplexType owning the attribute to check.
94 * @param definition the definition to check the attribute against.
95 * @param value the value to check.
96 * @return null if ok, or an instance of {@link FailedCheck}if the check
97 * failed.
98 */
99 public abstract FailedCheck innerCheck(CrawlerSettings settings,
100 ComplexType owner, Type definition, Object value);
101
102 /*** Get the default message to return if a check fails.
103 *
104 * @return the default message to return if a check fails.
105 */
106 protected String getDefaultMessage() {
107 return msg;
108 }
109
110 /*** Objects of this class represents failed constraint checks.
111 *
112 * @author John Erik Halse
113 */
114 public class FailedCheck {
115 private final String msg;
116 private final CrawlerSettings settings;
117 private final ComplexType owner;
118 private final Type definition;
119 private final Object value;
120 protected final ArrayList<Object> messageArguments
121 = new ArrayList<Object>();
122
123 /***
124 * Construct a new FailedCheck object.
125 *
126 * @param settings the CrawlerSettings object for which this check was
127 * executed.
128 * @param owner the ComplexType owning the attribute to check.
129 * @param definition the definition to check the attribute against.
130 * @param value the value to check.
131 * @param msg a message describing what went wrong and possibly hints to
132 * the user on how to fix it.
133 */
134 public FailedCheck(CrawlerSettings settings, ComplexType owner,
135 Type definition, Object value, String msg) {
136 this.msg = msg;
137 this.settings = settings;
138 this.owner = owner;
139 this.definition = definition;
140 this.value = value;
141 this.messageArguments.add(definition.getName());
142 this.messageArguments.add(value);
143 this.messageArguments.add(owner.getName());
144 }
145
146 /***
147 * Construct a new FailedCheck object using the constraints default
148 * message.
149 *
150 * @param settings the CrawlerSettings object for which this check was
151 * executed.
152 * @param owner the ComplexType owning the attribute to check.
153 * @param definition the definition to check the attribute against.
154 * @param value the value to check.
155 */
156 public FailedCheck(CrawlerSettings settings, ComplexType owner,
157 Type definition, Object value) {
158 this(settings, owner, definition, value, getDefaultMessage());
159 }
160
161 /*** Get the error message.
162 *
163 * @return the error message.
164 */
165 public String getMessage() {
166 return MessageFormat.format(msg, messageArguments.toArray());
167 }
168
169 /*** Get the severity level.
170 *
171 * @return the severity level.
172 */
173 public Level getLevel() {
174 return severity;
175 }
176
177 /*** Get the definition for the checked attribute.
178 *
179 * @return the definition for the checked attribute.
180 */
181 public Type getDefinition() {
182 return definition;
183 }
184
185 /*** Get the value of the checked attribute.
186 *
187 * @return the value of the checked attribute.
188 */
189 public Object getValue() {
190 return value;
191 }
192
193 /*** Get the {@link ComplexType} owning the checked attribute.
194 *
195 * @return the {@link ComplexType} owning the checked attribute.
196 */
197 public ComplexType getOwner() {
198 return owner;
199 }
200
201 /*** Get the {@link CrawlerSettings} for the checked attribute.
202 *
203 * @return the {@link CrawlerSettings} for the checked attribute.
204 */
205 public CrawlerSettings getSettings() {
206 return settings;
207 }
208
209 /*** Returns a human readeable string for the failed check.
210 * Returns the same as {@link #getMessage()}
211 *
212 * @return A human readeable string for the failed check.
213 */
214 public String toString() {
215 return getMessage();
216 }
217 }
218
219 /*** Compare this constraints level to another constraint.
220 * This method is implemented to let constraints be sorted with the highest
221 * level first.
222 *
223 * @param o a Constraint to compare to.
224 */
225 public int compareTo(Constraint o) {
226 Constraint c = (Constraint) o;
227 return c.severity.intValue() - severity.intValue();
228 }
229
230 }