/* * Copyright © 2013. Palomino Labs (http://palominolabs.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.palominolabs.crm.sf.soap; import com.codahale.metrics.MetricRegistry; import com.palominolabs.crm.sf.soap.jaxwsstub.apex.ApexPortType; import com.palominolabs.crm.sf.soap.jaxwsstub.metadata.MetadataPortType; import com.palominolabs.crm.sf.soap.jaxwsstub.partner.Soap; import javax.annotation.Nonnull; import javax.annotation.concurrent.ThreadSafe; /** * Caches the JAX-WS-generated bindings. These are memory hogs and somewhat slow to create which is why we spend so much * effort to cache them. * * All SF SOAP connections in one JVM should share a single BindingRepository. */ @ThreadSafe final class BindingRepository { private final PartnerBindingCache partnerBindingCache = new PartnerBindingCache(); private final MetadataBindingCache metadataBindingCache = new MetadataBindingCache(); private final ApexBindingCache apexBindingCache = new ApexBindingCache(); private final BindingConfigurer bindingConfigurer; BindingRepository(@Nonnull String partnerKey, MetricRegistry metricsRegistry) { this.bindingConfigurer = new BindingConfigurer(partnerKey, metricsRegistry); } /** * @param bindingConfig the config data to apply to the binding * * @return the configured binding */ @Nonnull Soap getPartnerBinding(@Nonnull BindingConfig bindingConfig) { Soap binding = this.partnerBindingCache.getBinding(); this.bindingConfigurer.configurePartnerBinding(binding, bindingConfig); return binding; } /** * Once a binding has been released, it may not be used anymore. * * @param binding the binding to release */ void releasePartnerBinding(@Nonnull Soap binding) { this.partnerBindingCache.releaseBinding(binding); } @Nonnull MetadataPortType getMetadataBinding(@Nonnull BindingConfig bindingConfig) { MetadataPortType binding = this.metadataBindingCache.getBinding(); this.bindingConfigurer.configureMetadataBinding(binding, bindingConfig); return binding; } void releaseMetadataBinding(@Nonnull MetadataPortType binding) { this.metadataBindingCache.releaseBinding(binding); } @Nonnull ApexPortType getApexBinding(@Nonnull BindingConfig bindingConfig) { ApexPortType binding = this.apexBindingCache.getBinding(); this.bindingConfigurer.configureApexBinding(binding, bindingConfig); return binding; } void releaseApexBinding(@Nonnull ApexPortType binding) { this.apexBindingCache.releaseBinding(binding); } @Nonnull BindingConfig getBindingConfigData(@Nonnull String username, @Nonnull String password, @Nonnull CallSemaphore callSemaphore, boolean sandboxOrg) throws ApiException { final Soap binding = this.partnerBindingCache.getBinding(); try { return this.bindingConfigurer .loginAndGetBindingConfigData(username, password, binding, callSemaphore, sandboxOrg); } finally { this.releasePartnerBinding(binding); } } }