View Javadoc
1   package org.apache.fulcrum.intake.validator;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.List;
23  
24  import org.apache.fulcrum.intake.IntakeException;
25  import org.apache.fulcrum.intake.model.Field;
26  import org.apache.fulcrum.intake.model.Group;
27  
28  /**
29   * Helper Class to manage relations between fields. The following
30   * comparisons are supported:
31   *
32   * <table>
33   * <caption>Validation rules</caption>
34   * <tr>
35   *   <th>Name</th><th>Valid Values</th><th>Default Value</th>
36   * </tr>
37   * <tr>
38   *   <td>less-than</td>
39   *   <td>&lt;name of other field&gt;</td>
40   *   <td>&nbsp;</td>
41   * </tr>
42   * <tr>
43   *   <td>greater-than</td>
44   *   <td>&lt;name of other field&gt;</td>
45   *   <td>&nbsp;</td>
46   * </tr>
47   * <tr>
48   *   <td>less-than-or-equal</td>
49   *   <td>&lt;name of other field&gt;</td>
50   *   <td>&nbsp;</td>
51   * </tr>
52   * <tr>
53   *   <td>greater-than-or-equal</td>
54   *   <td>&lt;name of other field&gt;</td>
55   *   <td>&nbsp;</td>
56   * </tr>
57   * </table>
58   *
59   * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
60   * @version $Id$
61   */
62  public class FieldReference
63  {
64  	public static enum Comparison
65  	{
66  	    /** Rule for "&lt;" comparison */
67  		LT ("less-than"),
68  
69  		/** Rule for "&gt;" comparison */
70  		GT ("greater-than"),
71  
72  	    /** Rule for "&lt;=" comparison */
73  		LTE ("less-than-or-equal"),
74  
75  	    /** Rule for "&gt;=" comparison */
76  		GTE ("greater-than-or-equal");
77  
78  		private final String text;
79  
80  		private Comparison(String text)
81  		{
82  			this.text = text;
83  		}
84  
85  		@Override
86  		public String toString()
87  		{
88  			return text;
89  		}
90  
91  		public static Comparison fromString(String string)
92  		{
93  		    if (string != null)
94  		    {
95  		    	for (Comparison c : Comparison.values())
96  		    	{
97  		    		if (string.equals(c.text))
98  		    		{
99  		    			return c;
100 		    		}
101 		    	}
102 		    }
103 
104 		    return null;
105 		}
106 	}
107 
108     /** Numeric comparison */
109     private Comparison compare = null;
110 
111     /** Name of referenced field */
112     private String fieldName = null;
113 
114     /** Error message */
115     private String message = null;
116 
117     /**
118      *  Constructor
119      */
120     public FieldReference()
121     {
122         // do nothing
123     }
124 
125     /**
126      * @return the comparison type
127      */
128     public Comparison getComparison()
129     {
130         return compare;
131     }
132 
133     /**
134      * @param compare the comparison type to set
135      */
136     public void setComparison(Comparison compare)
137     {
138         this.compare = compare;
139     }
140 
141     /**
142      * @return the field name
143      */
144     public String getFieldName()
145     {
146         return fieldName;
147     }
148 
149     /**
150      * @param fieldName the field name to set
151      */
152     public void setFieldName(String fieldName)
153     {
154         this.fieldName = fieldName;
155     }
156 
157     /**
158      * @return the message
159      */
160     public String getMessage()
161     {
162         return message;
163     }
164 
165     /**
166      * @param message the message to set
167      */
168     public void setMessage(String message)
169     {
170         this.message = message;
171     }
172 
173     /**
174      * Map the comparison strings to their numeric counterparts
175      *
176      * @param key the string representation of a comparison operator
177      * @return the numeric representation of the given comparison operator
178      */
179     public static Comparison getComparisonType(String key)
180     {
181     	return Comparison.fromString(key);
182     }
183 
184     /**
185      * Check the parsed value against the referenced fields
186      *
187      * @param fieldReferences List of field references to check
188      * @param compareCallback Callback to the actual compare operation
189      * @param value the parsed value of the related field
190      * @param group the group the related field belongs to
191      *
192      * @param <T> the field type
193      *
194      * @throws ValidationException if the validation against at least one related field fails
195      */
196     public static <T> void checkReferences(List<FieldReference> fieldReferences, CompareCallback<T> compareCallback,
197             T value, Group group)
198         throws ValidationException
199     {
200         for (FieldReference ref : fieldReferences)
201         {
202             boolean comp_true = true;
203 
204             try
205             {
206                 @SuppressWarnings("unchecked")
207                 Field<T> refField = (Field<T>) group.get(ref.getFieldName());
208 
209                 if (refField.isSet())
210                 {
211                     /*
212                      * Fields are processed in sequence so that our
213                      * reference field might have been set but not
214                      * yet validated. We check this here.
215                      */
216                     if (!refField.isValidated())
217                     {
218                         refField.validate();
219                     }
220 
221                     if (refField.isValid())
222                     {
223                         comp_true = compareCallback.compareValues(ref.getComparison(),
224                                 value,
225                                 refField.getValue());
226                     }
227                 }
228             }
229             catch (IntakeException e)
230             {
231                 throw new ValidationException(ref.getMessage());
232             }
233 
234             if (comp_true == false)
235             {
236                 throw new ValidationException(ref.getMessage());
237             }
238         }
239     }
240 }