001    /*
002     * Copyright 2011 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/ecl1.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.api.document;
017    
018    import java.io.Serializable;
019    import java.util.Collection;
020    
021    import javax.xml.bind.annotation.XmlAccessType;
022    import javax.xml.bind.annotation.XmlAccessorType;
023    import javax.xml.bind.annotation.XmlAnyElement;
024    import javax.xml.bind.annotation.XmlElement;
025    import javax.xml.bind.annotation.XmlRootElement;
026    import javax.xml.bind.annotation.XmlType;
027    
028    import org.apache.commons.lang.StringUtils;
029    import org.apache.commons.lang.builder.EqualsBuilder;
030    import org.apache.commons.lang.builder.HashCodeBuilder;
031    import org.apache.commons.lang.builder.ToStringBuilder;
032    import org.kuali.rice.core.api.CoreConstants;
033    import org.kuali.rice.core.api.mo.ModelBuilder;
034    import org.kuali.rice.core.api.mo.ModelObjectComplete;
035    import org.w3c.dom.Element;
036    
037    @XmlRootElement(name = DocumentLink.Constants.ROOT_ELEMENT_NAME)
038    @XmlAccessorType(XmlAccessType.NONE)
039    @XmlType(name = DocumentLink.Constants.TYPE_NAME, propOrder = {
040                DocumentLink.Elements.ID,
041                    DocumentLink.Elements.ORIGINATING_DOCUMENT_ID,
042                    DocumentLink.Elements.DESTINATION_DOCUMENT_ID,
043                    CoreConstants.CommonElements.FUTURE_ELEMENTS
044    })
045    public final class DocumentLink implements ModelObjectComplete, DocumentLinkContract {
046    
047            private static final long serialVersionUID = -1193048221115914280L;
048    
049            @XmlElement(name = Elements.ID, required = false)
050        private final String id;
051    
052        @XmlElement(name = Elements.ORIGINATING_DOCUMENT_ID, required = true)
053        private final String originatingDocumentId;
054        
055        @XmlElement(name = Elements.DESTINATION_DOCUMENT_ID, required = true)
056        private final String destinationDocumentId;
057            
058        @SuppressWarnings("unused")
059        @XmlAnyElement
060        private final Collection<Element> _futureElements = null;
061    
062        /**
063         * Private constructor used only by JAXB.
064         */
065        private DocumentLink() {
066            this.id = null;
067            this.originatingDocumentId = null;
068            this.destinationDocumentId = null;
069        }
070    
071        private DocumentLink(Builder builder) {
072            this.id = builder.getId();
073            this.originatingDocumentId = builder.getOriginatingDocumentId();
074            this.destinationDocumentId = builder.getDestinationDocumentId();
075        }
076    
077        @Override
078        public String getId() {
079            return this.id;
080        }
081        
082        @Override
083        public String getOriginatingDocumentId() {
084            return this.originatingDocumentId;
085        }
086    
087        @Override
088        public String getDestinationDocumentId() {
089            return this.destinationDocumentId;
090        }
091    
092        @Override
093        public int hashCode() {
094            return HashCodeBuilder.reflectionHashCode(this, Constants.HASH_CODE_EQUALS_EXCLUDE);
095        }
096    
097        @Override
098        public boolean equals(Object object) {
099            return EqualsBuilder.reflectionEquals(object, this, Constants.HASH_CODE_EQUALS_EXCLUDE);
100        }
101    
102        @Override
103        public String toString() {
104            return ToStringBuilder.reflectionToString(this);
105        }
106    
107        /**
108         * A builder which can be used to construct {@link DocumentLink} instances.  Enforces the constraints of the {@link DocumentLinkContract}.
109         */
110        public final static class Builder implements Serializable, ModelBuilder, DocumentLinkContract {
111    
112                    private static final long serialVersionUID = -6713990840543140054L;
113    
114                    private String id;
115            private String originatingDocumentId;
116            private String destinationDocumentId;
117    
118            private Builder(String originatingDocumentId, String destinationDocumentId) {
119                setOriginatingDocumentId(originatingDocumentId);
120                setDestinationDocumentId(destinationDocumentId);
121                if (getOriginatingDocumentId().equals(getDestinationDocumentId())) {
122                    throw new IllegalArgumentException("originating and destination document ids were the same, cannot link a document with itself");
123                }
124            }
125    
126            public static Builder create(String originatingDocumentId, String destinationDocumentId) {
127                return new Builder(originatingDocumentId, destinationDocumentId);
128            }
129    
130            public static Builder create(DocumentLinkContract contract) {
131                if (contract == null) {
132                    throw new IllegalArgumentException("contract was null");
133                }
134                Builder builder = create(contract.getOriginatingDocumentId(), contract.getDestinationDocumentId());
135                builder.setId(contract.getId());
136                return builder;
137            }
138    
139            public DocumentLink build() {
140                return new DocumentLink(this);
141            }
142    
143            @Override
144            public String getId() {
145                return this.id;
146            }
147            
148            @Override
149            public String getOriginatingDocumentId() {
150                return this.originatingDocumentId;
151            }
152    
153            @Override
154            public String getDestinationDocumentId() {
155                return this.destinationDocumentId;
156            }
157    
158            public void setId(String id) {
159                this.id = id;
160            }
161    
162            public void setOriginatingDocumentId(String originatingDocumentId) {
163                if (StringUtils.isBlank(originatingDocumentId)) {
164                    throw new IllegalArgumentException("originatingDocumentId was null or blank");
165                }
166                this.originatingDocumentId = originatingDocumentId;
167            }
168    
169            public void setDestinationDocumentId(String destinationDocumentId) {
170                    if (StringUtils.isBlank(destinationDocumentId)) {
171                    throw new IllegalArgumentException("destinationDocumentId was null or blank");
172                }
173                this.destinationDocumentId = destinationDocumentId;
174            }
175    
176        }
177    
178        /**
179         * Defines some internal constants used on this class.
180         */
181        static class Constants {
182            final static String ROOT_ELEMENT_NAME = "documentLink";
183            final static String TYPE_NAME = "DocumentLinkType";
184            final static String[] HASH_CODE_EQUALS_EXCLUDE = new String[] {CoreConstants.CommonElements.FUTURE_ELEMENTS };
185        }
186    
187        /**
188         * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
189         */
190        static class Elements {
191            final static String ID = "id";
192            final static String ORIGINATING_DOCUMENT_ID = "originatingDocumentId";
193            final static String DESTINATION_DOCUMENT_ID = "destinationDocumentId";
194        }
195    
196    }