View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.docsearch;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.search.SearchOperator;
20  import org.kuali.rice.core.framework.persistence.jdbc.sql.SQLUtils;
21  import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
22  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeDecimal;
23  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeFactory;
24  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
25  import org.kuali.rice.kew.service.KEWServiceLocator;
26  import org.kuali.rice.kew.api.KewApiConstants;
27  
28  import javax.persistence.CascadeType;
29  import javax.persistence.Column;
30  import javax.persistence.Entity;
31  import javax.persistence.FetchType;
32  import javax.persistence.GeneratedValue;
33  import javax.persistence.Id;
34  import javax.persistence.JoinColumn;
35  import javax.persistence.ManyToOne;
36  import javax.persistence.NamedQueries;
37  import javax.persistence.NamedQuery;
38  import javax.persistence.Table;
39  import javax.persistence.Transient;
40  import java.io.Serializable;
41  import java.math.BigDecimal;
42  import java.sql.ResultSet;
43  import java.sql.SQLException;
44  import java.text.DecimalFormat;
45  import java.text.NumberFormat;
46  import java.util.Arrays;
47  import java.util.List;
48  import java.util.regex.Matcher;
49  import java.util.regex.Pattern;
50  
51  /**
52   *
53   * @author Kuali Rice Team (rice.collab@kuali.org)
54   */
55  @Entity
56  @Table(name="KREW_DOC_HDR_EXT_FLT_T")
57  //@Sequence(name="KREW_SRCH_ATTR_S",property="searchableAttributeValueId")
58  @NamedQueries({
59  	@NamedQuery(name="SearchableAttributeFloatValue.FindByDocumentId", query="select s from SearchableAttributeFloatValue as s where s.documentId = :documentId"),
60  	@NamedQuery(name="SearchableAttributeFloatValue.FindByKey", query="select s from SearchableAttributeFloatValue as s where s.documentId = :documentId and s.searchableAttributeKey = :searchableAttributeKey")
61  })
62  public class SearchableAttributeFloatValue implements SearchableAttributeValue, Serializable {
63  
64      private static final long serialVersionUID = -6682101853805320760L;
65  
66      private static final String ATTRIBUTE_DATABASE_TABLE_NAME = "KREW_DOC_HDR_EXT_FLT_T";
67      private static final boolean DEFAULT_WILDCARD_ALLOWANCE_POLICY = false;
68      private static final boolean ALLOWS_RANGE_SEARCH = true;
69      private static final boolean ALLOWS_CASE_INSENSITIVE_SEARCH = false;
70      private static final String DEFAULT_VALIDATION_REGEX_EXPRESSION = "[-+]?[0-9]*\\.?[0-9]+";
71      private static final String ATTRIBUTE_XML_REPRESENTATION = KewApiConstants.SearchableAttributeConstants.DATA_TYPE_FLOAT;
72      private static final String DEFAULT_FORMAT_PATTERN = "";
73  
74      @Id
75      @GeneratedValue(generator="KREW_SRCH_ATTR_S")
76  	@Column(name="DOC_HDR_EXT_FLT_ID")
77  	private String searchableAttributeValueId;
78      @Column(name="KEY_CD")
79  	private String searchableAttributeKey;
80      @Column(name="VAL")
81  	private BigDecimal searchableAttributeValue;
82      @Transient
83      protected String ojbConcreteClass; // attribute needed for OJB polymorphism - do not alter!
84  
85      @Column(name="DOC_HDR_ID")
86  	private String documentId;
87      @ManyToOne(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST})
88  	@JoinColumn(name="DOC_HDR_ID", insertable=false, updatable=false)
89  	private DocumentRouteHeaderValue routeHeader;
90  
91      /**
92       * Default constructor.
93       */
94      public SearchableAttributeFloatValue() {
95          super();
96          this.ojbConcreteClass = this.getClass().getName();
97      }
98  
99      /* (non-Javadoc)
100      * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#setupAttributeValue(java.lang.String)
101      */
102     public void setupAttributeValue(String value) {
103         this.setSearchableAttributeValue(convertStringToBigDecimal(value));
104     }
105 
106     private BigDecimal convertStringToBigDecimal(String value) {
107         if (org.apache.commons.lang.StringUtils.isEmpty(value)) {
108             return null;
109         } else {
110             return new BigDecimal(value);
111         }
112     }
113 
114 	/* (non-Javadoc)
115 	 * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#setupAttributeValue(java.sql.ResultSet, java.lang.String)
116 	 */
117 	public void setupAttributeValue(ResultSet resultSet, String columnName) throws SQLException {
118 		this.setSearchableAttributeValue(resultSet.getBigDecimal(columnName));
119 	}
120 
121     /* (non-Javadoc)
122      * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#getSearchableAttributeDisplayValue(java.util.Map)
123      */
124     public String getSearchableAttributeDisplayValue() {
125 	    NumberFormat format = DecimalFormat.getInstance();
126 	    ((DecimalFormat)format).toPattern();
127 	    ((DecimalFormat)format).applyPattern(DEFAULT_FORMAT_PATTERN);
128 	    return format.format(getSearchableAttributeValue().doubleValue());
129 	}
130 
131     /* (non-Javadoc)
132 	 * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#getAttributeDataType()
133 	 */
134 	public String getAttributeDataType() {
135 		return ATTRIBUTE_XML_REPRESENTATION;
136 	}
137 
138 	/* (non-Javadoc)
139 	 * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#getAttributeTableName()
140 	 */
141 	public String getAttributeTableName() {
142 		return ATTRIBUTE_DATABASE_TABLE_NAME;
143 	}
144 
145     /* (non-Javadoc)
146 	 * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#allowsWildcardsByDefault()
147 	 */
148 	public boolean allowsWildcards() {
149 		return DEFAULT_WILDCARD_ALLOWANCE_POLICY;
150 	}
151 
152     /* (non-Javadoc)
153 	 * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#allowsCaseInsensitivity()
154 	 */
155 	public boolean allowsCaseInsensitivity() {
156 		return ALLOWS_CASE_INSENSITIVE_SEARCH;
157 	}
158 
159     /* (non-Javadoc)
160 	 * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#allowsRangeSearches()
161 	 */
162 	public boolean allowsRangeSearches() {
163 		return ALLOWS_RANGE_SEARCH;
164 	}
165 
166 	/* (non-Javadoc)
167 	 * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#isPassesDefaultValidation()
168 	 */
169     public boolean isPassesDefaultValidation(String valueEntered) {
170 
171     	boolean bRet = true;
172     	boolean bSplit = false;
173 
174 		if (StringUtils.contains(valueEntered, SearchOperator.BETWEEN.op())) {
175 			List<String> l = Arrays.asList(valueEntered.split("\\.\\."));
176 			for(String value : l){
177 				bSplit = true;
178 				if(!isPassesDefaultValidation(value)){
179 					bRet = false;
180 				}
181 			}
182 		}
183 		if (StringUtils.contains(valueEntered, SearchOperator.OR.op())) {
184 			//splitValueList.addAll(Arrays.asList(StringUtils.split(valueEntered, KRADConstants.OR_LOGICAL_OPERATOR)));
185 			List<String> l = Arrays.asList(StringUtils.split(valueEntered, SearchOperator.OR.op()));
186 			for(String value : l){
187 				bSplit = true;
188 				if(!isPassesDefaultValidation(value)){
189 					bRet = false;
190 				}
191 			}
192 		}
193 		if (StringUtils.contains(valueEntered, SearchOperator.AND.op())) {
194 			//splitValueList.addAll(Arrays.asList(StringUtils.split(valueEntered, KRADConstants.AND_LOGICAL_OPERATOR)));
195 			List<String> l = Arrays.asList(StringUtils.split(valueEntered, SearchOperator.AND.op()));
196 			for(String value : l){
197 				bSplit = true;
198 				if(!isPassesDefaultValidation(value)){
199 					bRet = false;
200 				}
201 			}
202 		}
203 
204 		if(bSplit){
205 			return bRet;
206 		}
207 
208 		Pattern pattern = Pattern.compile(DEFAULT_VALIDATION_REGEX_EXPRESSION);
209 		Matcher matcher = pattern.matcher(SQLUtils.cleanNumericOfValidOperators(valueEntered).trim()); 
210 		if(!matcher.matches()){
211 			bRet = false;
212 		}
213 
214 		return bRet;
215 
216     }
217 
218     /* (non-Javadoc)
219      * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#isRangeValid(java.lang.String, java.lang.String)
220      */
221     public Boolean isRangeValid(String lowerValue, String upperValue) {
222         if (allowsRangeSearches()) {
223             BigDecimal lower = null;
224             BigDecimal upper = null;
225             try{
226             	lower = convertStringToBigDecimal(lowerValue);
227             	upper = convertStringToBigDecimal(upperValue);
228             }catch(NumberFormatException ex){
229             	return false;
230             }
231             if ( (lower != null) && (upper != null) ) {
232                 return (lower.compareTo(upper) <= 0);
233             }
234             return true;
235         }
236         return null;
237     }
238 
239 	public String getOjbConcreteClass() {
240         return ojbConcreteClass;
241     }
242 
243     public void setOjbConcreteClass(String ojbConcreteClass) {
244         this.ojbConcreteClass = ojbConcreteClass;
245     }
246 
247     public DocumentRouteHeaderValue getRouteHeader() {
248         return routeHeader;
249     }
250 
251     public void setRouteHeader(DocumentRouteHeaderValue routeHeader) {
252         this.routeHeader = routeHeader;
253     }
254 
255     public String getDocumentId() {
256         return documentId;
257     }
258 
259     public void setDocumentId(String documentId) {
260         this.documentId = documentId;
261     }
262 
263     public String getSearchableAttributeKey() {
264         return searchableAttributeKey;
265     }
266 
267     public void setSearchableAttributeKey(String searchableAttributeKey) {
268         this.searchableAttributeKey = searchableAttributeKey;
269     }
270 
271     public BigDecimal getSearchableAttributeValue() {
272         return searchableAttributeValue;
273     }
274 
275     public void setSearchableAttributeValue(BigDecimal searchableAttributeValue) {
276         this.searchableAttributeValue = searchableAttributeValue;
277     }
278 
279     /**
280      * @deprecated USE method setSearchableAttributeValue(BigDecimal) instead
281      */
282     public void setSearchableAttributeValue(Float floatValueToTranslate) {
283         this.searchableAttributeValue = null;
284         if (floatValueToTranslate != null) {
285             this.searchableAttributeValue = new BigDecimal(floatValueToTranslate.toString());
286         }
287     }
288 
289     public String getSearchableAttributeValueId() {
290         return searchableAttributeValueId;
291     }
292 
293     public void setSearchableAttributeValueId(String searchableAttributeValueId) {
294         this.searchableAttributeValueId = searchableAttributeValueId;
295     }
296 
297 	//@PrePersist
298 	public void beforeInsert(){
299 		OrmUtils.populateAutoIncValue(this, KEWServiceLocator.getEntityManagerFactory().createEntityManager());
300 	}
301 
302     @Override
303     public DocumentAttributeDecimal toDocumentAttribute() {
304         return DocumentAttributeFactory.createDecimalAttribute(getSearchableAttributeKey(), getSearchableAttributeValue());
305     }
306 
307 
308 }
309