001/**
002 * Copyright 2005-2015 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.group;
017
018import com.google.common.collect.Maps;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.rice.core.api.CoreConstants;
021import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
022import org.kuali.rice.core.api.mo.ModelBuilder;
023import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
024import org.kuali.rice.kim.api.KimConstants;
025import org.w3c.dom.Element;
026
027import javax.xml.bind.annotation.XmlAccessType;
028import javax.xml.bind.annotation.XmlAccessorType;
029import javax.xml.bind.annotation.XmlAnyElement;
030import javax.xml.bind.annotation.XmlElement;
031import javax.xml.bind.annotation.XmlRootElement;
032import javax.xml.bind.annotation.XmlType;
033import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
034import java.io.Serializable;
035import java.util.Collection;
036import java.util.Collections;
037import 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})
053public 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}