001    /**
002     * Copyright 2005-2014 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     */
016    package org.kuali.rice.kew.framework.document.search;
017    
018    import java.io.Serializable;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.List;
022    import javax.xml.bind.annotation.XmlAccessType;
023    import javax.xml.bind.annotation.XmlAccessorType;
024    import javax.xml.bind.annotation.XmlAnyElement;
025    import javax.xml.bind.annotation.XmlElement;
026    import javax.xml.bind.annotation.XmlElementWrapper;
027    import javax.xml.bind.annotation.XmlRootElement;
028    import javax.xml.bind.annotation.XmlType;
029    
030    import org.apache.commons.collections.CollectionUtils;
031    import org.kuali.rice.core.api.CoreConstants;
032    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
033    import org.kuali.rice.core.api.mo.ModelBuilder;
034    import org.kuali.rice.core.api.mo.ModelObjectUtils;
035    import org.kuali.rice.core.api.uif.RemotableAttributeFieldContract;
036    import org.kuali.rice.core.api.uif.RemotableAttributeField;
037    import org.w3c.dom.Element;
038    
039    /**
040     * An immutable data transfer object implementation of the {@link DocumentSearchResultSetConfigurationContract}.
041     * Instances of this class should be constructed using the nested {@link Builder} class.
042     *
043     * @author Kuali Rice Team (rice.collab@kuali.org)
044     */
045    @XmlRootElement(name = DocumentSearchResultSetConfiguration.Constants.ROOT_ELEMENT_NAME)
046    @XmlAccessorType(XmlAccessType.NONE)
047    @XmlType(name = DocumentSearchResultSetConfiguration.Constants.TYPE_NAME, propOrder = {
048        DocumentSearchResultSetConfiguration.Elements.OVERRIDE_SEARCHABLE_ATTRIBUTES,
049        DocumentSearchResultSetConfiguration.Elements.CUSTOM_FIELD_NAMES_TO_ADD,
050        DocumentSearchResultSetConfiguration.Elements.STANDARD_RESULT_FIELDS_TO_REMOVE,
051        DocumentSearchResultSetConfiguration.Elements.ADDITIONAL_ATTRIBUTE_FIELDS,
052        CoreConstants.CommonElements.FUTURE_ELEMENTS
053    })
054    public final class DocumentSearchResultSetConfiguration extends AbstractDataTransferObject
055            implements DocumentSearchResultSetConfigurationContract {
056    
057        @XmlElement(name = Elements.OVERRIDE_SEARCHABLE_ATTRIBUTES, required = true)
058        private final boolean overrideSearchableAttributes;
059    
060        @XmlElementWrapper(name = Elements.CUSTOM_FIELD_NAMES_TO_ADD, required = false)
061        @XmlElement(name = Elements.CUSTOM_FIELD_NAME_TO_ADD, required = false)
062        private final List<String> customFieldNamesToAdd;
063    
064        @XmlElementWrapper(name = Elements.STANDARD_RESULT_FIELDS_TO_REMOVE, required = false)
065        @XmlElement(name = Elements.STANDARD_RESULT_FIELD_TO_REMOVE, required = false)
066        private final List<StandardResultField> standardResultFieldsToRemove;
067    
068        @XmlElementWrapper(name = Elements.ADDITIONAL_ATTRIBUTE_FIELDS, required = false)
069        @XmlElement(name = Elements.ADDITIONAL_ATTRIBUTE_FIELD, required = false)
070        private final List<RemotableAttributeField> additionalAttributeFields;
071        
072        @SuppressWarnings("unused")
073        @XmlAnyElement
074        private final Collection<Element> _futureElements = null;
075    
076        /**
077         * Private constructor used only by JAXB.
078         */
079        @SuppressWarnings("unused")
080        private DocumentSearchResultSetConfiguration() {
081            this.overrideSearchableAttributes = false;
082            this.customFieldNamesToAdd = null;
083            this.standardResultFieldsToRemove = null;
084            this.additionalAttributeFields = null;
085        }
086    
087        private DocumentSearchResultSetConfiguration(Builder builder) {
088            this.overrideSearchableAttributes = builder.isOverrideSearchableAttributes();
089            this.customFieldNamesToAdd = ModelObjectUtils.createImmutableCopy(builder.getCustomFieldNamesToAdd());
090            this.standardResultFieldsToRemove =
091                    ModelObjectUtils.createImmutableCopy(builder.getStandardResultFieldsToRemove());
092            this.additionalAttributeFields = ModelObjectUtils.buildImmutableCopy(builder.getAdditionalAttributeFields());
093        }
094    
095        @Override
096        public boolean isOverrideSearchableAttributes() {
097            return this.overrideSearchableAttributes;
098        }
099    
100        @Override
101        public List<String> getCustomFieldNamesToAdd() {
102            return this.customFieldNamesToAdd;
103        }
104    
105        @Override
106        public List<StandardResultField> getStandardResultFieldsToRemove() {
107            return this.standardResultFieldsToRemove;
108        }
109    
110        @Override
111        public List<RemotableAttributeField> getAdditionalAttributeFields() {
112            return this.additionalAttributeFields;
113        }
114    
115        /**
116         * A builder which can be used to construct {@link DocumentSearchResultSetConfiguration} instances.  Enforces the
117         * constraints of the {@link DocumentSearchResultSetConfigurationContract}.
118         */
119        public final static class Builder implements Serializable, ModelBuilder, DocumentSearchResultSetConfigurationContract {
120    
121            private boolean overrideSearchableAttributes;
122            private List<String> customFieldNamesToAdd;
123            private List<StandardResultField> standardResultFieldsToRemove;
124            private List<RemotableAttributeField.Builder> additionalAttributeFields;
125    
126            private Builder() {
127                setOverrideSearchableAttributes(false);
128                setCustomFieldNamesToAdd(new ArrayList<String>());
129                setStandardResultFieldsToRemove(new ArrayList<StandardResultField>());
130                setAdditionalAttributeFields(new ArrayList<RemotableAttributeField.Builder>());
131            }
132    
133            /**
134             * Creates new empty builder instance.  The various lists on this builder are initialized to empty lists.  The
135             * {@code overrideSearchableAttribute} boolean property is initialized to "false".
136             *
137             * @return a new empty builder instance
138             */
139            public static Builder create() {
140                return new Builder();
141            }
142    
143            /**
144             * Creates a new builder instance initialized with copies of the properties from the given contract.
145             *
146             * @param contract the contract from which to copy properties
147             *
148             * @return a builder instance initialized with properties from the given contract
149             *
150             * @throws IllegalArgumentException if the given contract is null
151             */
152            public static Builder create(DocumentSearchResultSetConfigurationContract contract) {
153                if (contract == null) {
154                    throw new IllegalArgumentException("contract was null");
155                }
156                Builder builder = create();
157                builder.setOverrideSearchableAttributes(contract.isOverrideSearchableAttributes());
158                if (CollectionUtils.isNotEmpty(contract.getCustomFieldNamesToAdd())) {
159                    builder.setCustomFieldNamesToAdd(new ArrayList<String>(contract.getCustomFieldNamesToAdd()));
160                }
161                if (CollectionUtils.isNotEmpty(contract.getStandardResultFieldsToRemove())) {
162                    builder.setStandardResultFieldsToRemove(
163                            new ArrayList<StandardResultField>(contract.getStandardResultFieldsToRemove()));
164                }
165                if (CollectionUtils.isNotEmpty(contract.getAdditionalAttributeFields())) {
166                    for (RemotableAttributeFieldContract attributeField : contract.getAdditionalAttributeFields()) {
167                        builder.getAdditionalAttributeFields().add(RemotableAttributeField.Builder.create(attributeField));
168                    }
169                }
170                return builder;
171            }
172    
173            @Override
174            public DocumentSearchResultSetConfiguration build() {
175                return new DocumentSearchResultSetConfiguration(this);
176            }
177    
178            @Override
179            public boolean isOverrideSearchableAttributes() {
180                return this.overrideSearchableAttributes;
181            }
182    
183            @Override
184            public List<String> getCustomFieldNamesToAdd() {
185                return this.customFieldNamesToAdd;
186            }
187    
188            @Override
189            public List<StandardResultField> getStandardResultFieldsToRemove() {
190                return this.standardResultFieldsToRemove;
191            }
192    
193            @Override
194            public List<RemotableAttributeField.Builder> getAdditionalAttributeFields() {
195                return this.additionalAttributeFields;
196            }
197    
198            public void setOverrideSearchableAttributes(boolean overrideSearchableAttributes) {
199                this.overrideSearchableAttributes = overrideSearchableAttributes;
200            }
201    
202            public void setCustomFieldNamesToAdd(List<String> customFieldNamesToAdd) {
203                this.customFieldNamesToAdd = customFieldNamesToAdd;
204            }
205    
206            public void setStandardResultFieldsToRemove(List<StandardResultField> standardResultFieldsToRemove) {
207                this.standardResultFieldsToRemove = standardResultFieldsToRemove;
208            }
209    
210            public void setAdditionalAttributeFields(List<RemotableAttributeField.Builder> additionalAttributeFields) {
211                this.additionalAttributeFields = additionalAttributeFields;
212            }
213    
214        }
215    
216        /**
217         * Defines some internal constants used on this class.
218         */
219        static class Constants {
220            final static String ROOT_ELEMENT_NAME = "documentSearchResultSetConfiguration";
221            final static String TYPE_NAME = "DocumentSearchResultSetConfigurationType";
222        }
223    
224        /**
225         * A private class which exposes constants which define the XML element names to use when this object is marshalled
226         * to XML.
227         */
228        static class Elements {
229            final static String OVERRIDE_SEARCHABLE_ATTRIBUTES = "overrideSearchableAttributes";
230            final static String CUSTOM_FIELD_NAMES_TO_ADD = "customFieldNamesToAdd";
231            final static String CUSTOM_FIELD_NAME_TO_ADD = "customFieldNameToAdd";
232            final static String STANDARD_RESULT_FIELDS_TO_REMOVE = "standardResultFieldsToRemove";
233            final static String STANDARD_RESULT_FIELD_TO_REMOVE = "standardResultFieldToRemove";
234            final static String ADDITIONAL_ATTRIBUTE_FIELDS = "additionalAttributeFields";
235            final static String ADDITIONAL_ATTRIBUTE_FIELD = "additionalAttributeField";
236        }
237    
238    }