/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2011, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.webservices.webserviceref;

import static org.jboss.as.webservices.webserviceref.SecurityActions.getContextClassLoader;
import static org.jboss.as.webservices.webserviceref.SecurityActions.setContextClassLoader;

import javax.naming.Referenceable;
import javax.naming.spi.ObjectFactory;

import org.jboss.as.ee.component.InjectionSource;
import org.jboss.as.naming.ManagedReferenceFactory;
import org.jboss.as.naming.ValueManagedReferenceFactory;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.value.Value;
import org.jboss.ws.common.utils.DelegateClassLoader;
import org.jboss.wsf.spi.SPIProvider;
import org.jboss.wsf.spi.SPIProviderResolver;
import org.jboss.wsf.spi.classloading.ClassLoaderProvider;
import org.jboss.wsf.spi.metadata.j2ee.serviceref.UnifiedServiceRefMetaData;
import org.jboss.wsf.spi.serviceref.ServiceRefHandler;
import org.jboss.wsf.spi.serviceref.ServiceRefHandlerFactory;

/**
 * WebServiceRef injection source.
 *
 * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
 */
final class WSRefValueSource extends InjectionSource implements Value<Object> {
    private final UnifiedServiceRefMetaData serviceRef;

    WSRefValueSource(final UnifiedServiceRefMetaData serviceRef) {
        this.serviceRef = serviceRef;
    }

    public void getResourceValue(final ResolutionContext resolutionContext, final ServiceBuilder<?> serviceBuilder, final DeploymentPhaseContext phaseContext, final Injector<ManagedReferenceFactory> injector) throws DeploymentUnitProcessingException {
        final ManagedReferenceFactory factory = new ValueManagedReferenceFactory(this);
        serviceBuilder.addInjection(injector, factory);
    }

    public Object getValue() throws IllegalStateException, IllegalArgumentException {
        final ClassLoader oldCL = getContextClassLoader();
        try {
            final ClassLoader integrationCL = ClassLoaderProvider.getDefaultProvider().getServerIntegrationClassLoader();
            final ClassLoader newCL = new DelegateClassLoader(integrationCL, oldCL);
            setContextClassLoader(newCL);
            final Referenceable referenceable = getReferenceable(integrationCL);
            final Class<?> clazz = Class.forName(referenceable.getReference().getFactoryClassName(), true, integrationCL);
            final ObjectFactory factory = (ObjectFactory)clazz.newInstance();
            return factory.getObjectInstance(referenceable.getReference(), null, null, null);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        } finally {
            setContextClassLoader(oldCL);
        }
    }

    private Referenceable getReferenceable(final ClassLoader loader) {
        final SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
        final ServiceRefHandler serviceRefHandler = spiProvider.getSPI(ServiceRefHandlerFactory.class, loader).getServiceRefHandler();
        return serviceRefHandler.createReferenceable(serviceRef);
    }

}
@@ -2062,24 +2062,84 @@
 RefHandler;%0A
+import org.jboss.wsf.spi.serviceref.ServiceRefHandler.Type;%0A
 import org.j
@@ -2188,16 +2188,16 @@
 actory;%0A
-
 %0A/**%0A * 
@@ -3162,161 +3162,49 @@
 L = 
-ClassLoaderProvider.getDefaultProvider().getServerIntegrationClassLoader();%0A            final ClassLoader newCL = new DelegateClassLoader(integrationCL, 
+new DelegateClassLoader(getClassLoader(),
 oldC
@@ -3241,19 +3241,27 @@
 sLoader(
-new
+integration
 CL);%0A   
@@ -3730,24 +3730,24 @@
 %7D finally %7B%0A
-
             
@@ -3789,24 +3789,371 @@
    %7D%0A    %7D%0A%0A
+    private ClassLoader getClassLoader() %7B%0A        ClassLoaderProvider provider = ClassLoaderProvider.getDefaultProvider();%0A        if (!Type.JAXRPC.equals(serviceRef.getType())) %7B%0A            return provider.getServerIntegrationClassLoader();%0A        %7D else %7B%0A            return provider.getServerJAXRPCIntegrationClassLoader();%0A        %7D%0A    %7D%0A%0A
     private 

Set proper CL