blob: d7abd021f6dcb3a8d6df9172d384b3bd034656fc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.tuscany.sca.implementation.java.invocation;
import java.lang.reflect.Method;
import org.apache.tuscany.sca.context.ComponentContextFactory;
import org.apache.tuscany.sca.context.PropertyValueFactory;
import org.apache.tuscany.sca.context.RequestContextFactory;
import org.apache.tuscany.sca.core.factory.InstanceWrapper;
import org.apache.tuscany.sca.core.factory.ObjectFactory;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.core.scope.Scope;
import org.apache.tuscany.sca.core.scope.ScopedImplementationProvider;
import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
import org.apache.tuscany.sca.implementation.java.JavaImplementation;
import org.apache.tuscany.sca.implementation.java.JavaResourceImpl;
import org.apache.tuscany.sca.implementation.java.injection.RequestContextObjectFactory;
import org.apache.tuscany.sca.implementation.java.injection.ResourceHost;
import org.apache.tuscany.sca.implementation.java.injection.ResourceObjectFactory;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.oasisopen.sca.ComponentContext;
import org.oasisopen.sca.RequestContext;
/**
* @version $Rev$ $Date$
*/
public class JavaImplementationProvider implements ScopedImplementationProvider {
private JavaImplementation implementation;
private JavaComponentContextProvider componentContextProvider;
private RequestContextFactory requestContextFactory;
public JavaImplementationProvider(RuntimeComponent component,
JavaImplementation implementation,
ProxyFactory proxyService,
DataBindingExtensionPoint dataBindingRegistry,
PropertyValueFactory propertyValueObjectFactory,
ComponentContextFactory componentContextFactory,
RequestContextFactory requestContextFactory) {
super();
this.implementation = implementation;
this.requestContextFactory = requestContextFactory;
try {
JavaInstanceFactoryProvider configuration = new JavaInstanceFactoryProvider(implementation);
configuration.setProxyFactory(proxyService);
componentContextProvider =
new JavaComponentContextProvider(component,
configuration,
dataBindingRegistry,
propertyValueObjectFactory,
componentContextFactory,
requestContextFactory);
Scope scope = getScope();
componentContextProvider.configureProperties(component.getProperties());
handleResources(implementation, proxyService);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private void handleResources(JavaImplementation componentType, ProxyFactory proxyService) {
for (JavaResourceImpl resource : componentType.getResources().values()) {
String name = resource.getName();
ObjectFactory<?> objectFactory =
(ObjectFactory<?>)componentContextProvider.getInstanceFactoryProvider().getFactories().get(resource.getElement());
if (objectFactory == null) {
Class<?> type = resource.getElement().getType();
if (ComponentContext.class.equals(type)) {
objectFactory = new JavaComponentContextFactory(componentContextProvider);
} else if (RequestContext.class.equals(type)) {
objectFactory = new RequestContextObjectFactory(requestContextFactory, componentContextProvider.getComponent());
} else if (String.class.equals(type)) {
objectFactory = new JavaComponentNameFactory(componentContextProvider);
} else {
boolean optional = resource.isOptional();
String mappedName = resource.getMappedName();
objectFactory = createResourceObjectFactory(type, mappedName, optional, null);
}
}
componentContextProvider.addResourceFactory(name, objectFactory);
}
}
private <T> ResourceObjectFactory<T> createResourceObjectFactory(Class<T> type,
String mappedName,
boolean optional,
ResourceHost host) {
return new ResourceObjectFactory<T>(type, mappedName, optional, host);
}
public Invoker createInvoker(RuntimeComponentService service, Operation operation) {
try {
return componentContextProvider.createInvoker(operation, service.getInterfaceContract());
} catch (NoSuchMethodException e) {
// It's possible that the instance being invoked is a user-specified
// callback object that isn't an instance of the component implementation
// class. As an attempt to deal with this, look up a method object from
// the service interface. This isn't foolproof, as it's possible that
// the service interface isn't a Java interface, or that the callback
// object has the right method signature without implementing the
// callback interface. There is code in JavaImplementationInvoker
// to deal with these possibilities.
Interface iface = service.getInterfaceContract().getInterface();
if (iface instanceof JavaInterface) {
try {
Method method = JavaInterfaceUtil.findMethod(((JavaInterface)iface).getJavaClass(), operation);
return new JavaImplementationInvoker(operation, method, componentContextProvider.getComponent(), service.getInterfaceContract());
} catch (NoSuchMethodException e1) {
throw new IllegalArgumentException(e1);
}
} else {
return new JavaImplementationInvoker(operation, componentContextProvider.getComponent(), service.getInterfaceContract());
}
}
}
public boolean supportsOneWayInvocation() {
return false;
}
public Scope getScope() {
return new Scope(implementation.getJavaScope().getScope());
}
public void start() {
componentContextProvider.start();
}
public void stop() {
componentContextProvider.stop();
}
public InstanceWrapper<?> createInstanceWrapper() {
return componentContextProvider.createInstanceWrapper();
}
public boolean isEagerInit() {
return implementation.isEagerInit();
}
}