001/** 002 * Copyright 2005-2016 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.ksb.impl.bus; 017 018import javax.xml.namespace.QName; 019 020import org.apache.commons.lang.StringUtils; 021import org.kuali.rice.ksb.api.bus.Endpoint; 022import org.kuali.rice.ksb.api.bus.ServiceConfiguration; 023import org.kuali.rice.ksb.api.registry.ServiceDescriptor; 024import org.kuali.rice.ksb.api.registry.ServiceInfo; 025import org.kuali.rice.ksb.api.registry.ServiceRegistry; 026 027public final class RemoteService { 028 029 private final ServiceInfo serviceInfo; 030 private final ServiceRegistry serviceRegistry; 031 032 private final Object endpointAcquisitionLock = new Object(); 033 private volatile Endpoint endpoint; 034 035 public RemoteService(ServiceInfo serviceInfo, ServiceRegistry serviceRegistry) { 036 validateServiceInfo(serviceInfo); 037 if (serviceRegistry == null) { 038 throw new IllegalArgumentException("serviceRegistry cannot be null"); 039 } 040 this.serviceInfo = serviceInfo; 041 this.serviceRegistry = serviceRegistry; 042 } 043 044 private static void validateServiceInfo(ServiceInfo serviceInfo) { 045 if (serviceInfo == null) { 046 throw new IllegalArgumentException("serviceInfo cannot be null"); 047 } 048 if (serviceInfo.getServiceId() == null) { 049 throw new IllegalArgumentException("serviceInfo must have a serviceId but was null"); 050 } 051 } 052 053 public QName getServiceName() { 054 return serviceInfo.getServiceName(); 055 } 056 057 public ServiceInfo getServiceInfo() { 058 return serviceInfo; 059 } 060 061 public Endpoint getEndpoint() { 062 // double-checked locking idiom - see Effective Java, Item 71 063 Endpoint internalEndpoint = this.endpoint; 064 if (internalEndpoint == null) { 065 synchronized (endpointAcquisitionLock) { 066 internalEndpoint = this.endpoint; 067 if (internalEndpoint == null) { 068 this.endpoint = internalEndpoint = new LazyEndpoint(constructServiceConfiguration()); 069 } 070 } 071 } 072 return internalEndpoint; 073 } 074 075 protected ServiceConfiguration constructServiceConfiguration() { 076 ServiceDescriptor serviceDescriptor = serviceRegistry.getServiceDescriptor(serviceInfo.getServiceDescriptorId()); 077 if (serviceDescriptor == null) { 078 throw new IllegalStateException("Failed to locate ServiceDescriptor for ServiceInfo with serviceDescriptorId=" + serviceInfo.getServiceDescriptorId()); 079 } else if (StringUtils.isBlank(serviceDescriptor.getDescriptor())) { 080 throw new IllegalStateException("ServiceDescriptor descriptor value is blank or null for descriptor with serviceEndpointId=" + serviceInfo.getServiceId()); 081 } 082 return ServiceConfigurationSerializationHandler.unmarshallFromXml(serviceDescriptor.getDescriptor()); 083 } 084 085 @Override 086 public boolean equals(Object obj) { 087 if (!(obj instanceof RemoteService)) { 088 return false; 089 } 090 return serviceInfo.equals(((RemoteService)obj).getServiceInfo()); 091 } 092 093 @Override 094 public int hashCode() { 095 return serviceInfo.hashCode(); 096 } 097 098}