001    package org.kuali.rice.ksb.api.registry;
002    
003    import java.io.Serializable;
004    import java.util.Collection;
005    
006    import javax.xml.bind.annotation.XmlAccessType;
007    import javax.xml.bind.annotation.XmlAccessorType;
008    import javax.xml.bind.annotation.XmlAnyElement;
009    import javax.xml.bind.annotation.XmlElement;
010    import javax.xml.bind.annotation.XmlRootElement;
011    import javax.xml.bind.annotation.XmlType;
012    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
013    import javax.xml.namespace.QName;
014    
015    import org.apache.commons.lang.StringUtils;
016    import org.apache.commons.lang.builder.EqualsBuilder;
017    import org.apache.commons.lang.builder.HashCodeBuilder;
018    import org.apache.commons.lang.builder.ToStringBuilder;
019    import org.kuali.rice.core.api.CoreConstants;
020    import org.kuali.rice.core.api.mo.ModelBuilder;
021    import org.kuali.rice.core.api.mo.ModelObjectComplete;
022    import org.kuali.rice.core.util.jaxb.QNameAsStringAdapter;
023    import org.w3c.dom.Element;
024    
025    /**
026     * Immutable implementation of the {@link ServiceInfoContract} interface.
027     * Includes standard configuration information about a service that has been
028     * published to the service registry.
029     * 
030     * @author Kuali Rice Team (rice.collab@kuali.org)
031     *
032     */
033    @XmlRootElement(name = ServiceInfo.Constants.ROOT_ELEMENT_NAME)
034    @XmlAccessorType(XmlAccessType.NONE)
035    @XmlType(name = ServiceInfo.Constants.TYPE_NAME, propOrder = {
036        ServiceInfo.Elements.SERVICE_ID,
037        ServiceInfo.Elements.SERVICE_NAME,
038        ServiceInfo.Elements.ENDPOINT_URL,
039        ServiceInfo.Elements.INSTANCE_ID,
040        ServiceInfo.Elements.APPLICATION_ID,
041        ServiceInfo.Elements.SERVER_IP_ADDRESS,
042        ServiceInfo.Elements.TYPE,
043        ServiceInfo.Elements.SERVICE_VERSION,
044        ServiceInfo.Elements.STATUS,
045        ServiceInfo.Elements.SERVICE_DESCRIPTOR_ID,
046        ServiceInfo.Elements.CHECKSUM,
047        CoreConstants.CommonElements.VERSION_NUMBER,
048        CoreConstants.CommonElements.FUTURE_ELEMENTS
049    })
050    public final class ServiceInfo implements ModelObjectComplete, ServiceInfoContract {
051    
052            private static final long serialVersionUID = 4793306414624564991L;
053            
054            @XmlElement(name = Elements.SERVICE_ID, required = false)
055        private final String serviceId;
056            
057            @XmlJavaTypeAdapter(QNameAsStringAdapter.class)
058        @XmlElement(name = Elements.SERVICE_NAME, required = true)
059        private final QName serviceName;
060        
061        @XmlElement(name = Elements.ENDPOINT_URL, required = true)
062        private final String endpointUrl;
063        
064        @XmlElement(name = Elements.INSTANCE_ID, required = true)
065        private final String instanceId;
066        
067        @XmlElement(name = Elements.APPLICATION_ID, required = true)
068        private final String applicationId;
069        
070        @XmlElement(name = Elements.SERVER_IP_ADDRESS, required = true)
071        private final String serverIpAddress;
072        
073        @XmlElement(name = Elements.TYPE, required = true)
074        private final String type;
075        
076        @XmlElement(name = Elements.SERVICE_VERSION, required = true)
077        private final String serviceVersion;
078        
079        @XmlJavaTypeAdapter(ServiceEndpointStatus.Adapter.class)
080        @XmlElement(name = Elements.STATUS, required = true)
081        private final String status;
082        
083        @XmlElement(name = Elements.SERVICE_DESCRIPTOR_ID, required = false)
084        private final String serviceDescriptorId;
085        
086        @XmlElement(name = Elements.CHECKSUM, required = true)
087        private final String checksum;
088        
089        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
090        private final Long versionNumber;
091        
092        @SuppressWarnings("unused")
093        @XmlAnyElement
094        private final Collection<Element> _futureElements = null;
095    
096        /**
097         * Private constructor used only by JAXB.
098         * 
099         */
100        private ServiceInfo() {
101            this.serviceId = null;
102            this.serviceName = null;
103            this.endpointUrl = null;
104            this.instanceId = null;
105            this.applicationId = null;
106            this.serverIpAddress = null;
107            this.type = null;
108            this.serviceVersion = null;
109            this.status = null;
110            this.serviceDescriptorId = null;
111            this.checksum = null;
112            this.versionNumber = null;
113        }
114    
115        private ServiceInfo(Builder builder) {
116            this.serviceId = builder.getServiceId();
117            this.serviceName = builder.getServiceName();
118            this.endpointUrl = builder.getEndpointUrl();
119            this.instanceId = builder.getInstanceId();
120            this.applicationId = builder.getApplicationId();
121            this.serverIpAddress = builder.getServerIpAddress();
122            this.type = builder.getType();
123            this.serviceVersion = builder.getServiceVersion();
124            ServiceEndpointStatus builderStatus = builder.getStatus();
125            this.status = builderStatus == null ? null : builderStatus.getCode();
126            this.serviceDescriptorId = builder.getServiceDescriptorId();
127            this.checksum = builder.getChecksum();
128            this.versionNumber = builder.getVersionNumber();
129        }
130    
131        @Override
132        public String getServiceId() {
133            return this.serviceId;
134        }
135    
136        @Override
137        public QName getServiceName() {
138            return this.serviceName;
139        }
140    
141        @Override
142        public String getEndpointUrl() {
143            return this.endpointUrl;
144        }
145        
146        @Override
147        public String getInstanceId() {
148            return this.instanceId;
149        }
150    
151        @Override
152        public String getApplicationId() {
153            return this.applicationId;
154        }
155    
156        @Override
157        public String getServerIpAddress() {
158            return this.serverIpAddress;
159        }
160        
161        @Override
162        public String getType() {
163            return this.type;
164        }
165        
166        @Override
167        public String getServiceVersion() {
168            return this.serviceVersion;
169        }
170        
171        @Override
172        public ServiceEndpointStatus getStatus() {
173            return ServiceEndpointStatus.fromCode(this.status);
174        }
175    
176        @Override
177        public String getServiceDescriptorId() {
178            return this.serviceDescriptorId;
179        }
180        
181        @Override
182        public String getChecksum() {
183            return this.checksum;
184        }
185    
186        @Override
187        public Long getVersionNumber() {
188            return this.versionNumber;
189        }
190    
191        @Override
192        public int hashCode() {
193            return HashCodeBuilder.reflectionHashCode(this, Constants.HASH_CODE_EQUALS_EXCLUDE);
194        }
195    
196        @Override
197        public boolean equals(Object object) {
198            return EqualsBuilder.reflectionEquals(object, this, Constants.HASH_CODE_EQUALS_EXCLUDE);
199        }
200    
201        @Override
202        public String toString() {
203            return ToStringBuilder.reflectionToString(this);
204        }
205    
206        /**
207         * A builder which can be used to construct {@link ServiceInfo} instances.
208         * Enforces the constraints of the {@link ServiceInfoContract}.
209         */
210        public final static class Builder
211            implements Serializable, ModelBuilder, ServiceInfoContract
212        {
213    
214                    private static final long serialVersionUID = 4424090938369742940L;
215    
216                    private String serviceId;
217            private QName serviceName;
218            private String endpointUrl;
219            private String instanceId;
220            private String applicationId;
221            private String serverIpAddress;
222            private String type;
223            private String serviceVersion;
224            private ServiceEndpointStatus status;
225            private String serviceDescriptorId;
226            private String checksum;
227            private Long versionNumber;
228    
229            private Builder() {}
230    
231            public static Builder create() {
232                return new Builder();
233            }
234    
235            public static Builder create(ServiceInfoContract contract) {
236                if (contract == null) {
237                    throw new IllegalArgumentException("contract was null");
238                }
239                Builder builder = create();
240                builder.setServiceId(contract.getServiceId());
241                builder.setServiceName(contract.getServiceName());
242                builder.setEndpointUrl(contract.getEndpointUrl());
243                builder.setInstanceId(contract.getInstanceId());
244                builder.setApplicationId(contract.getApplicationId());
245                builder.setServerIpAddress(contract.getServerIpAddress());
246                builder.setType(contract.getType());
247                builder.setServiceVersion(contract.getServiceVersion());
248                builder.setStatus(contract.getStatus());
249                builder.setServiceDescriptorId(contract.getServiceDescriptorId());
250                builder.setChecksum(contract.getChecksum());
251                builder.setVersionNumber(contract.getVersionNumber());
252                return builder;
253            }
254    
255            public ServiceInfo build() {
256                    validateAll();
257                return new ServiceInfo(this);
258            }
259    
260            @Override
261            public String getServiceId() {
262                return this.serviceId;
263            }
264    
265            @Override
266            public QName getServiceName() {
267                return this.serviceName;
268            }
269    
270            @Override
271            public String getEndpointUrl() {
272                return this.endpointUrl;
273            }
274            
275            @Override
276            public String getInstanceId() {
277                return this.instanceId;
278            }
279    
280            @Override
281            public String getApplicationId() {
282                return this.applicationId;
283            }
284    
285            @Override
286            public String getServerIpAddress() {
287                return this.serverIpAddress;
288            }
289            
290            @Override
291            public String getType() {
292                    return this.type;
293            }
294            
295            @Override
296            public String getServiceVersion() {
297                    return this.serviceVersion;
298            }
299    
300            @Override
301            public ServiceEndpointStatus getStatus() {
302                    return this.status;
303            }
304            
305            @Override
306            public String getServiceDescriptorId() {
307                return this.serviceDescriptorId;
308            }
309            
310            @Override
311            public String getChecksum() {
312                return this.checksum;
313            }
314    
315            @Override
316            public Long getVersionNumber() {
317                return this.versionNumber;
318            }
319    
320            public void setServiceId(String serviceId) {
321                this.serviceId = serviceId;
322            }
323    
324            public void setServiceName(QName serviceName) {
325                validateServiceName(serviceName);
326                this.serviceName = serviceName;
327            }
328    
329            public void setEndpointUrl(String endpointUrl) {
330                validateEndpointUrl(endpointUrl);
331                this.endpointUrl = endpointUrl;
332            }
333            
334            public void setInstanceId(String instanceId) {
335                validateInstanceId(instanceId);
336                this.instanceId = instanceId;
337            }
338    
339            public void setApplicationId(String applicationId) {
340                validateApplicationId(applicationId);
341                this.applicationId = applicationId;
342            }
343    
344            public void setServerIpAddress(String serverIpAddress) {
345                    validateServerIpAddress(serverIpAddress);
346                this.serverIpAddress = serverIpAddress;
347            }
348            
349            public void setType(String type) {
350                    validateType(type);
351                    this.type = type;
352            }
353            
354            public void setServiceVersion(String serviceVersion) {
355                    validateServiceVersion(serviceVersion);
356                    this.serviceVersion = serviceVersion;
357            }
358            
359            public void setStatus(ServiceEndpointStatus status) {
360                    validateStatus(status);
361                    this.status = status;
362            }
363    
364            public void setServiceDescriptorId(String serviceDescriptorId) {
365                this.serviceDescriptorId = serviceDescriptorId;
366            }
367            
368            public void setChecksum(String checksum) {
369                validateChecksum(checksum);
370                this.checksum = checksum;
371            }
372    
373            public void setVersionNumber(Long versionNumber) {
374                this.versionNumber = versionNumber;
375            }
376            
377            private void assertNotNull(String name, Object object) {
378                    if (object == null) {
379                            throw new IllegalArgumentException(name + " was null");
380                    }
381            }
382            
383            private void assertNotBlank(String name, String value) {
384                    assertNotNull(name, value);
385                    if (StringUtils.isBlank(value)) {
386                            throw new IllegalArgumentException(name + " was blank");
387                    }
388            }
389            
390            private void validateServiceName(QName serviceName) {
391                    assertNotNull("serviceName", serviceName);
392            }
393            
394            private void validateEndpointUrl(String endpointUrl) {
395                    assertNotBlank("endpointUrl", endpointUrl);
396            }
397            
398            private void validateInstanceId(String instanceId) {
399                    assertNotBlank("instanceId", instanceId);
400            }
401            
402            private void validateApplicationId(String applicationId) {
403                    assertNotBlank("applicationId", applicationId);
404            }
405            
406            private void validateServerIpAddress(String serverIpAddress) {
407                    assertNotBlank("serverIpAddress", serverIpAddress);
408            }
409            
410            private void validateType(String type) {
411                    assertNotBlank("type", type);
412            }
413    
414            private void validateServiceVersion(String serviceVersion) {
415                    assertNotBlank("serviceVersion", serviceVersion);
416            }
417            
418            private void validateStatus(ServiceEndpointStatus status) {
419                    assertNotNull("status", status);
420            }
421            
422            private void validateChecksum(String checksum) {
423                    assertNotBlank("checksum", checksum);
424            }
425            
426            private void validateAll() {
427                    validateServiceName(serviceName);
428                validateEndpointUrl(endpointUrl);
429                validateInstanceId(instanceId);
430                validateApplicationId(applicationId);
431                validateServerIpAddress(serverIpAddress);
432                validateType(type);
433                validateServiceVersion(serviceVersion);
434                validateStatus(status);
435                validateChecksum(checksum);
436            }
437    
438        }
439    
440    
441        /**
442         * Defines some internal constants used on this class.
443         * 
444         */
445        static class Constants {
446    
447            final static String ROOT_ELEMENT_NAME = "serviceInfo";
448            final static String TYPE_NAME = "ServiceInfoType";
449            final static String[] HASH_CODE_EQUALS_EXCLUDE = new String[] {CoreConstants.CommonElements.FUTURE_ELEMENTS };
450    
451        }
452    
453    
454        /**
455         * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
456         * 
457         */
458        static class Elements {
459    
460            final static String SERVICE_ID = "serviceId";
461            final static String SERVICE_NAME = "serviceName";
462            final static String ENDPOINT_URL = "endpointUrl";
463            final static String INSTANCE_ID = "instanceId";
464            final static String APPLICATION_ID = "applicationId";
465            final static String SERVER_IP_ADDRESS = "serverIpAddress";
466            final static String TYPE = "type";
467            final static String SERVICE_VERSION = "serviceVersion";
468            final static String STATUS = "status";
469            final static String SERVICE_DESCRIPTOR_ID = "serviceDescriptorId";
470            final static String CHECKSUM = "checksum";
471    
472        }
473    
474    }
475