001/**
002 * Copyright 2005-2018 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.kim.api.type;
017
018import java.io.Serializable;
019import java.util.Collection;
020import javax.xml.bind.annotation.XmlAccessType;
021import javax.xml.bind.annotation.XmlAccessorType;
022import javax.xml.bind.annotation.XmlAnyElement;
023import javax.xml.bind.annotation.XmlElement;
024import javax.xml.bind.annotation.XmlRootElement;
025import javax.xml.bind.annotation.XmlType;
026
027import org.apache.commons.lang.StringUtils;
028import org.kuali.rice.core.api.CoreConstants;
029import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
030import org.kuali.rice.core.api.mo.ModelBuilder;
031import org.kuali.rice.core.api.uif.RemotableAttributeField;
032import org.w3c.dom.Element;
033
034@XmlRootElement(name = KimAttributeField.Constants.ROOT_ELEMENT_NAME)
035@XmlAccessorType(XmlAccessType.NONE)
036@XmlType(name = KimAttributeField.Constants.TYPE_NAME, propOrder = {
037    KimAttributeField.Elements.ATTRIBUTE_FIELD,
038    KimAttributeField.Elements.ID,
039    KimAttributeField.Elements.UNIQUE,
040    CoreConstants.CommonElements.FUTURE_ELEMENTS
041})
042public final class KimAttributeField
043    extends AbstractDataTransferObject
044    implements KimAttributeFieldContract
045{
046
047    @XmlElement(name = Elements.ATTRIBUTE_FIELD, required = true)
048    private final RemotableAttributeField attributeField;
049    @XmlElement(name = Elements.ID, required = true)
050    private final String id;
051    @XmlElement(name = Elements.UNIQUE, required = false)
052    private final boolean unique;
053
054    @SuppressWarnings("unused")
055    @XmlAnyElement
056    private final Collection<Element> _futureElements = null;
057
058    /**
059     * Private constructor used only by JAXB.
060     * 
061     */
062    private KimAttributeField() {
063        this.attributeField = null;
064        this.id = null;
065        this.unique = false;
066    }
067
068    private KimAttributeField(Builder builder) {
069        this.attributeField = builder.getAttributeField().build();
070        this.id = builder.getId();
071        this.unique = builder.isUnique();
072    }
073
074    @Override
075    public RemotableAttributeField getAttributeField() {
076        return this.attributeField;
077    }
078
079    @Override
080    public String getId() {
081        return this.id;
082    }
083
084    @Override
085    public boolean isUnique() {
086        return this.unique;
087    }
088
089    /**
090     * Utility method to search a collection of attribute fields and returns
091     * a field for a give attribute name.
092     *
093     * @param attributeName the name of the attribute to search for.  Cannot be blank or null.
094     * @param fields cannot be null.
095     *
096     * @return the attribute field or null if not found.
097     */
098    public static KimAttributeField findAttribute(String attributeName, Collection<KimAttributeField> fields) {
099        if (StringUtils.isBlank(attributeName)) {
100            throw new IllegalArgumentException("attributeName is blank");
101        }
102
103        if (fields == null) {
104            throw new IllegalArgumentException("errors is null");
105        }
106
107        for (KimAttributeField field : fields) {
108            if (attributeName.equals(field.getAttributeField().getName())) {
109                return field;
110            }
111        }
112        return null;
113    }
114
115    /**
116     * A builder which can be used to construct {@link KimAttributeField} instances.  Enforces the constraints of the {@link KimAttributeFieldContract}.
117     * 
118     */
119    public final static class Builder
120        implements Serializable, ModelBuilder, KimAttributeFieldContract
121    {
122
123        private RemotableAttributeField.Builder attributeField;
124        private String id;
125        private boolean unique;
126
127        private Builder(RemotableAttributeField.Builder attributeField, String id) {
128            setAttributeField(attributeField);
129            setId(id);
130        }
131
132        public static Builder create(RemotableAttributeField.Builder attributeField, String id) {
133            return new Builder(attributeField, id);
134        }
135
136        public static Builder create(KimAttributeFieldContract contract) {
137            if (contract == null) {
138                throw new IllegalArgumentException("contract was null");
139            }
140            Builder b = create(RemotableAttributeField.Builder.create(contract.getAttributeField()), contract.getId());
141            b.setUnique(contract.isUnique());
142            return b;
143        }
144
145        public KimAttributeField build() {
146            return new KimAttributeField(this);
147        }
148
149        @Override
150        public RemotableAttributeField.Builder getAttributeField() {
151            return this.attributeField;
152        }
153
154        @Override
155        public String getId() {
156            return this.id;
157        }
158
159        @Override
160        public boolean isUnique() {
161            return this.unique;
162        }
163
164        public void setAttributeField(RemotableAttributeField.Builder attributeField) {
165            if (attributeField == null) {
166                throw new IllegalArgumentException("attributeField is null");
167            }
168
169            this.attributeField = attributeField;
170        }
171
172        public void setId(String id) {
173            if (StringUtils.isBlank(id)) {
174                throw new IllegalArgumentException("id is blank");
175            }
176            this.id = id;
177        }
178
179        public void setUnique(boolean unique) {
180            this.unique = unique;
181        }
182
183    }
184
185
186    /**
187     * Defines some internal constants used on this class.
188     * 
189     */
190    static class Constants {
191
192        final static String ROOT_ELEMENT_NAME = "kimAttributeField";
193        final static String TYPE_NAME = "KimAttributeFieldType";
194
195    }
196
197
198    /**
199     * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
200     * 
201     */
202    static class Elements {
203
204        final static String ATTRIBUTE_FIELD = "attributeField";
205        final static String ID = "id";
206        final static String UNIQUE = "unique";
207    }
208
209}