001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kew.docsearch;
017
018import org.apache.commons.lang.ObjectUtils;
019import org.apache.commons.lang.StringUtils;
020import org.hibernate.annotations.GenericGenerator;
021import org.hibernate.annotations.Parameter;
022import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
023import org.kuali.rice.kew.api.document.attribute.DocumentAttribute;
024import org.kuali.rice.kew.api.document.attribute.DocumentAttributeFactory;
025import org.kuali.rice.kew.api.document.attribute.DocumentAttributeString;
026import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
027import org.kuali.rice.kew.service.KEWServiceLocator;
028import org.kuali.rice.kew.api.KewApiConstants;
029
030import javax.persistence.*;
031import java.io.Serializable;
032import java.sql.ResultSet;
033import java.sql.SQLException;
034
035
036/**
037 *
038 * @author Kuali Rice Team (rice.collab@kuali.org)
039 */
040@Entity
041@Table(name="KREW_DOC_HDR_EXT_T")
042//@Sequence(name="KREW_SRCH_ATTR_S",property="searchableAttributeValueId")
043@NamedQueries({
044        @NamedQuery(name="SearchableAttributeStringValue.FindByDocumentId", query="select s from SearchableAttributeStringValue as s where s.documentId = :documentId"),
045        @NamedQuery(name="SearchableAttributeStringValue.FindByKey", query="select s from SearchableAttributeStringValue as s where s.documentId = :documentId and s.searchableAttributeKey = :searchableAttributeKey")
046})
047public class SearchableAttributeStringValue implements CaseAwareSearchableAttributeValue, Serializable {
048
049    private static final long serialVersionUID = 8696089933682052078L;
050
051    private static final String ATTRIBUTE_DATABASE_TABLE_NAME = "KREW_DOC_HDR_EXT_T";
052    private static final boolean DEFAULT_WILDCARD_ALLOWANCE_POLICY = true;
053    private static final boolean ALLOWS_RANGE_SEARCH = true;
054    private static final boolean ALLOWS_CASE_INSENSITIVE_SEARCH = true;
055    private static final String ATTRIBUTE_XML_REPRESENTATION = KewApiConstants.SearchableAttributeConstants.DATA_TYPE_STRING;
056    private static final int STRING_MAX_LENGTH = 2000; // should match table creation
057
058    @Id
059    @GeneratedValue(generator="KREW_SRCH_ATTR_S")
060        @GenericGenerator(name="KREW_SRCH_ATTR_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={
061                        @Parameter(name="sequence_name",value="KREW_SRCH_ATTR_S"),
062                        @Parameter(name="value_column",value="id")
063        })
064        @Column(name="DOC_HDR_EXT_ID")
065        private String searchableAttributeValueId;
066    @Column(name="KEY_CD")
067        private String searchableAttributeKey;
068    @Column(name="VAL")
069        private String searchableAttributeValue;
070    @Transient
071    protected String ojbConcreteClass; // attribute needed for OJB polymorphism - do not alter!
072
073    @Column(name="DOC_HDR_ID")
074        private String documentId;
075    @ManyToOne(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST})
076        @JoinColumn(name="DOC_HDR_ID", insertable=false, updatable=false)
077        private DocumentRouteHeaderValue routeHeader;
078
079    /**
080     * Default constructor.
081     */
082    public SearchableAttributeStringValue() {
083        super();
084        this.ojbConcreteClass = this.getClass().getName();
085    }
086
087    /* (non-Javadoc)
088     * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#setupAttributeValue(java.lang.String)
089     */
090    public void setupAttributeValue(String value) {
091        this.setSearchableAttributeValue(value);
092    }
093
094        /* (non-Javadoc)
095         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#setupAttributeValue(java.sql.ResultSet, java.lang.String)
096         */
097        public void setupAttributeValue(ResultSet resultSet, String columnName) throws SQLException {
098                this.setSearchableAttributeValue(resultSet.getString(columnName));
099        }
100
101        /* (non-Javadoc)
102         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#getSearchableAttributeDisplayValue()
103         */
104    public String getSearchableAttributeDisplayValue() {
105        return getSearchableAttributeValue();
106    }
107
108        /* (non-Javadoc)
109         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#getAttributeDataType()
110         */
111        public String getAttributeDataType() {
112                return ATTRIBUTE_XML_REPRESENTATION;
113        }
114
115        /* (non-Javadoc)
116         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#getAttributeTableName()
117         */
118        public String getAttributeTableName() {
119                return ATTRIBUTE_DATABASE_TABLE_NAME;
120        }
121
122    /* (non-Javadoc)
123         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#allowsWildcardsByDefault()
124         */
125        public boolean allowsWildcards() {
126                return DEFAULT_WILDCARD_ALLOWANCE_POLICY;
127        }
128
129    /* (non-Javadoc)
130         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#allowsCaseInsensitivity()
131         */
132        public boolean allowsCaseInsensitivity() {
133                return ALLOWS_CASE_INSENSITIVE_SEARCH;
134        }
135
136    /* (non-Javadoc)
137         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#allowsRangeSearches()
138         */
139        public boolean allowsRangeSearches() {
140                return ALLOWS_RANGE_SEARCH;
141        }
142
143        /**
144         * @return true if the {@code valueEntered} parameter is not null and is equal to or
145         * less than the specified max length defined by {@link #STRING_MAX_LENGTH}
146         *
147         * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#isPassesDefaultValidation()
148         */
149        public boolean isPassesDefaultValidation(String valueEntered) {
150            if (valueEntered != null && (valueEntered.length() > STRING_MAX_LENGTH)) {
151                return false;
152            }
153                return true;
154        }
155
156    /* (non-Javadoc)
157     * @see org.kuali.rice.kew.docsearch.SearchableAttributeValue#isRangeValid(java.lang.String, java.lang.String)
158     */
159    public Boolean isRangeValid(String lowerValue, String upperValue) {
160        return isRangeValid(lowerValue, upperValue, true);
161    }
162
163    /* (non-Javadoc)
164     * @see org.kuali.rice.kew.docsearch.CaseAwareSearchableAttributeValue#isRangeValid(java.lang.String, java.lang.String, boolean)
165     */
166    public Boolean isRangeValid(String lowerValue, String upperValue, boolean caseSensitive) {
167        if (allowsRangeSearches()) {
168            return StringUtils.isBlank(lowerValue) ||
169                   StringUtils.isBlank(upperValue) ||
170                   (caseSensitive ?
171                     ObjectUtils.compare(lowerValue, upperValue) <= 0 :
172                     String.CASE_INSENSITIVE_ORDER.compare(lowerValue, upperValue) <= 0);
173        }
174        return null;
175    }
176
177        public String getOjbConcreteClass() {
178                return ojbConcreteClass;
179        }
180
181        public void setOjbConcreteClass(String ojbConcreteClass) {
182                this.ojbConcreteClass = ojbConcreteClass;
183        }
184
185        public DocumentRouteHeaderValue getRouteHeader() {
186                return routeHeader;
187        }
188
189        public void setRouteHeader(DocumentRouteHeaderValue routeHeader) {
190                this.routeHeader = routeHeader;
191        }
192
193        public String getDocumentId() {
194                return documentId;
195        }
196
197        public void setDocumentId(String documentId) {
198                this.documentId = documentId;
199        }
200
201        public String getSearchableAttributeKey() {
202                return searchableAttributeKey;
203        }
204
205        public void setSearchableAttributeKey(String searchableAttributeKey) {
206                this.searchableAttributeKey = searchableAttributeKey;
207        }
208
209        public String getSearchableAttributeValue() {
210                return searchableAttributeValue;
211        }
212
213        public void setSearchableAttributeValue(String searchableAttributeValue) {
214                this.searchableAttributeValue = searchableAttributeValue;
215        }
216
217        public String getSearchableAttributeValueId() {
218                return searchableAttributeValueId;
219        }
220
221        public void setSearchableAttributeValueId(String searchableAttributeValueId) {
222                this.searchableAttributeValueId = searchableAttributeValueId;
223        }
224
225        //@PrePersist
226        public void beforeInsert(){
227                OrmUtils.populateAutoIncValue(this, KEWServiceLocator.getEntityManagerFactory().createEntityManager());
228        }
229
230    @Override
231    public DocumentAttributeString toDocumentAttribute() {
232        return DocumentAttributeFactory.createStringAttribute(getSearchableAttributeKey(), getSearchableAttributeValue());
233    }
234}
235