001    /**
002     * Copyright 2005-2013 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.kim.api.group;
017    
018    import com.google.common.collect.Maps;
019    import org.apache.commons.lang.StringUtils;
020    import org.kuali.rice.core.api.CoreConstants;
021    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
022    import org.kuali.rice.core.api.mo.ModelBuilder;
023    import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
024    import org.kuali.rice.kim.api.KimConstants;
025    import org.w3c.dom.Element;
026    
027    import javax.xml.bind.annotation.XmlAccessType;
028    import javax.xml.bind.annotation.XmlAccessorType;
029    import javax.xml.bind.annotation.XmlAnyElement;
030    import javax.xml.bind.annotation.XmlElement;
031    import javax.xml.bind.annotation.XmlRootElement;
032    import javax.xml.bind.annotation.XmlType;
033    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
034    import java.io.Serializable;
035    import java.util.Collection;
036    import java.util.Collections;
037    import java.util.Map;
038    
039    @XmlRootElement(name = Group.Constants.ROOT_ELEMENT_NAME)
040    @XmlAccessorType(XmlAccessType.NONE)
041    @XmlType(name = Group.Constants.TYPE_NAME, propOrder = {
042            Group.Elements.ID,
043            Group.Elements.NAMESPACE_CODE,
044            Group.Elements.NAME,
045            Group.Elements.DESCRIPTION,
046            Group.Elements.KIM_TYPE_ID,
047            Group.Elements.ATTRIBUTES,
048            Group.Elements.ACTIVE,
049            CoreConstants.CommonElements.VERSION_NUMBER,
050            CoreConstants.CommonElements.OBJECT_ID,
051            CoreConstants.CommonElements.FUTURE_ELEMENTS
052    })
053    public final class Group extends AbstractDataTransferObject implements GroupContract {
054        @XmlElement(name = Elements.ID, required = false)
055        private final String id;
056    
057        @XmlElement(name = Elements.NAMESPACE_CODE, required = true)
058        private final String namespaceCode;
059    
060        @XmlElement(name = Elements.NAME, required = true)
061        private final String name;
062    
063        @XmlElement(name = Elements.DESCRIPTION, required = false)
064        private final String description;
065    
066        @XmlElement(name = Elements.KIM_TYPE_ID, required = true)
067        private final String kimTypeId;
068    
069        @XmlElement(name = Elements.ATTRIBUTES, required = false)
070        @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
071        private final Map<String, String> attributes;
072    
073        @XmlElement(name = Elements.ACTIVE, required = false)
074        private final boolean active;
075    
076        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
077        private final Long versionNumber;
078    
079        @XmlElement(name = CoreConstants.CommonElements.OBJECT_ID, required = false)
080        private final String objectId;
081    
082        @SuppressWarnings("unused")
083        @XmlAnyElement
084        private final Collection<Element> _futureElements = null;
085    
086        private Group() {
087            this.id = null;
088            this.namespaceCode = null;
089            this.name = null;
090            this.description = null;
091            this.kimTypeId = null;
092            this.attributes = null;
093            this.versionNumber = null;
094            this.objectId = null;
095            this.active = false;
096        }
097    
098        public Group(Builder builder) {
099            id = builder.getId();
100            namespaceCode = builder.getNamespaceCode();
101            name = builder.getName();
102            description = builder.getDescription();
103            kimTypeId = builder.getKimTypeId();
104            this.attributes = builder.getAttributes() != null ? builder.getAttributes() : Collections.<String, String>emptyMap();
105            versionNumber = builder.getVersionNumber();
106            objectId = builder.getObjectId();
107            active = builder.isActive();
108        }
109    
110    
111        /**
112         * This builder constructs an Group enforcing the constraints of the {@link org.kuali.rice.kim.api.group.GroupContract}.
113         */
114        public static class Builder implements GroupContract, ModelBuilder, Serializable {
115            private String id;
116            private String namespaceCode;
117            private String name;
118            private String description;
119            private String kimTypeId;
120            private Map<String, String> attributes = Collections.emptyMap();
121            private boolean active;
122            private Long versionNumber;
123            private String objectId;
124    
125            private Builder(String namespaceCode, String name, String kimTypeId) {
126                setNamespaceCode(namespaceCode);
127                setName(name);
128                setKimTypeId(kimTypeId);
129            }
130    
131            /**
132             * creates a Group with the required fields.
133             */
134            public static Builder create(String namespaceCode, String name, String kimTypeId) {
135                return new Builder(namespaceCode, name, kimTypeId);
136            }
137    
138            /**
139             * creates a Group from an existing {@link org.kuali.rice.kim.api.group.GroupContract}.
140             */
141            public static Builder create(GroupContract contract) {
142                if (contract == null) {
143                    throw new IllegalArgumentException("GroupContract is null");
144                }
145                Builder builder = new Builder(contract.getNamespaceCode(), contract.getName(), contract.getKimTypeId());
146                builder.setId(contract.getId());
147                builder.setDescription(contract.getDescription());
148    
149                if (contract.getAttributes() != null) {
150                    builder.setAttributes(contract.getAttributes());
151                }
152    
153                builder.setActive(contract.isActive());
154                builder.setVersionNumber(contract.getVersionNumber());
155                builder.setObjectId(contract.getObjectId());
156                return builder;
157            }
158    
159            @Override
160            public String getId() {
161                return id;
162            }
163    
164            public void setId(String id) {
165                if (StringUtils.isWhitespace(id)) {
166                    throw new IllegalArgumentException("id is blank");
167                }
168                this.id = id;
169            }
170    
171            @Override
172            public String getNamespaceCode() {
173                return namespaceCode;
174            }
175    
176            public void setNamespaceCode(String namespaceCode) {
177                if (StringUtils.isEmpty(namespaceCode)) {
178                    throw new IllegalArgumentException("namespaceCode is empty");
179                }
180                this.namespaceCode = namespaceCode;
181            }
182    
183            @Override
184            public String getName() {
185                return name;
186            }
187    
188            public void setName(String name) {
189                if (StringUtils.isEmpty(name)) {
190                    throw new IllegalArgumentException("name is empty");
191                }
192                this.name = name;
193            }
194    
195            @Override
196            public String getDescription() {
197                return description;
198            }
199    
200            public void setDescription(String description) {
201                this.description = description;
202            }
203    
204            @Override
205            public String getKimTypeId() {
206                return kimTypeId;
207            }
208    
209            public void setKimTypeId(String kimTypeId) {
210                if (StringUtils.isEmpty(kimTypeId)) {
211                    throw new IllegalArgumentException("kimTypeId is empty");
212                }
213                this.kimTypeId = kimTypeId;
214            }
215    
216            @Override
217            public Map<String, String> getAttributes() {
218                return attributes;
219            }
220    
221            public void setAttributes(Map<String, String> attributes) {
222                this.attributes = Collections.unmodifiableMap(Maps.newHashMap(attributes));
223            }
224    
225            @Override
226            public boolean isActive() {
227                return active;
228            }
229    
230            public void setActive(boolean active) {
231                this.active = active;
232            }
233    
234            @Override
235            public Long getVersionNumber() {
236                return versionNumber;
237            }
238    
239            public void setVersionNumber(Long versionNumber) {
240                this.versionNumber = versionNumber;
241            }
242    
243            @Override
244            public String getObjectId() {
245                return objectId;
246            }
247    
248            public void setObjectId(String objectId) {
249                this.objectId = objectId;
250            }
251    
252            @Override
253            public Group build() {
254                return new Group(this);
255            }
256        }
257    
258        @Override
259        public String getId() {
260            return id;
261        }
262    
263        @Override
264        public String getNamespaceCode() {
265            return namespaceCode;
266        }
267    
268        @Override
269        public String getName() {
270            return name;
271        }
272    
273        @Override
274        public String getDescription() {
275            return description;
276        }
277    
278        @Override
279        public String getKimTypeId() {
280            return kimTypeId;
281        }
282    
283        @Override
284        public Map<String, String> getAttributes() {
285            return attributes;
286        }
287    
288        @Override
289        public boolean isActive() {
290            return active;
291        }
292    
293        @Override
294        public Long getVersionNumber() {
295            return versionNumber;
296        }
297    
298        @Override
299        public String getObjectId() {
300            return objectId;
301        }
302    
303        /**
304         * Defines some internal constants used on this class.
305         */
306        static class Constants {
307            final static String ROOT_ELEMENT_NAME = "group";
308            final static String TYPE_NAME = "GroupType";
309        }
310    
311        /**
312         * A private class which exposes constants which define the XML element names to use
313         * when this object is marshalled to XML.
314         */
315        static class Elements {
316            final static String ID = "id";
317            final static String NAMESPACE_CODE = "namespaceCode";
318            final static String NAME = "name";
319            final static String DESCRIPTION = "description";
320            final static String KIM_TYPE_ID = "kimTypeId";
321            final static String ATTRIBUTES = "attributes";
322            final static String ACTIVE = "active";
323        }
324    
325        public static class Cache {
326            public static final String NAME = KimConstants.Namespaces.KIM_NAMESPACE_2_0 + "/" + Group.Constants.TYPE_NAME;
327        }
328    }