/** * * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. * * 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 org.apache.tuscany.container.rhino.context; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.tuscany.container.rhino.rhino.RhinoScript; import org.apache.tuscany.container.rhino.rhino.RhinoScriptInstance; import org.apache.tuscany.core.context.AtomicContext; import org.apache.tuscany.core.context.CoreRuntimeException; import org.apache.tuscany.core.context.QualifiedName; import org.apache.tuscany.core.context.TargetException; import org.apache.tuscany.core.context.event.InstanceCreated; import org.apache.tuscany.core.context.impl.AbstractContext; import org.apache.tuscany.core.extension.ExternalServiceInvoker; import org.apache.tuscany.core.wire.ProxyCreationException; import org.apache.tuscany.core.wire.SourceWireFactory; import org.apache.tuscany.core.wire.TargetWireFactory; import org.apache.tuscany.core.wire.WireFactory; import org.osoa.sca.ServiceRuntimeException; public class CopyOfJavaScriptComponentContext extends AbstractContext implements AtomicContext { private RhinoScript rhinoScript; private Map properties; private List sourceProxyFactories; private Map targetProxyFactories; public CopyOfJavaScriptComponentContext(String name, Map properties, List sourceProxyFactories, Map targetProxyFactories, RhinoScript rhinoScript) { super(name); this.properties = properties; this.rhinoScript = rhinoScript; this.sourceProxyFactories = sourceProxyFactories; this.targetProxyFactories = targetProxyFactories; } public Object getInstance(QualifiedName qName) throws TargetException { return getInstance(qName, true); } public void init() throws TargetException { getInstance(null, false); } public void destroy() throws TargetException { } private synchronized Object getInstance(QualifiedName qName, boolean notify) throws TargetException { String portName = qName.getPortName(); WireFactory targetFactory; if (portName != null) { targetFactory = targetProxyFactories.get(portName); } else { // FIXME The port name is null here, either locateService needs more information (the expected interface) to // select the correct port, or we need to return a factory that matches the whole set of services exposed by // the component. targetFactory = targetProxyFactories.values().iterator().next(); } if (targetFactory == null) { TargetException e = new TargetException("Target service not found"); e.setIdentifier(qName.getPortName()); e.addContextName(getName()); throw e; } try { Object proxy = targetFactory.createProxy(); // createProxy(new Class[] { iface }); if (notify) { publish(new InstanceCreated(this)); } return proxy; } catch (ProxyCreationException e) { TargetException te = new TargetException("Error returning target", e); e.setIdentifier(qName.getPortName()); e.addContextName(getName()); throw te; } } public Object getTargetInstance() throws TargetException { Map contexts = createServiceReferences(); contexts.putAll(properties); final RhinoScriptInstance rhinoScriptInstance = rhinoScript.createRhinoScriptInstance(contexts); ExternalServiceInvoker esi = new ExternalServiceInvoker() { public Object invoke(String methodName, Object[] args) { return rhinoScriptInstance.invokeFunction(methodName, args); } }; return esi; } /** * Creates a map containing any ServiceReferences */ private Map createServiceReferences() { try { Map context = new HashMap(); for (SourceWireFactory proxyFactory : sourceProxyFactories) { Object referenceProxy = createReferenceProxy(proxyFactory); context.put(proxyFactory.getConfiguration().getReferenceName(), referenceProxy); } return context; } catch (ProxyCreationException e) { throw new ServiceRuntimeException(e); } } private Object createReferenceProxy(SourceWireFactory proxyFactory) throws ProxyCreationException { Object proxy = proxyFactory.createProxy(); Class proxyClass = proxy.getClass(); if (Proxy.isProxyClass(proxyClass)) { Class[] ifaces = proxyClass.getInterfaces(); Class[] newIfaces = new Class[ifaces.length+1]; System.arraycopy(ifaces,0,newIfaces,0,ifaces.length); newIfaces[ifaces.length] = E4XReference.class; InvocationHandler ih = Proxy.getInvocationHandler(proxy); proxy = Proxy.newProxyInstance(proxyClass.getClassLoader(), newIfaces, ih); } return proxy; } interface E4XReference { public Object process(Object xml); } public boolean isEagerInit() { return false; } public boolean isDestroyable() { return false; } public void start() throws CoreRuntimeException { } public void stop() throws CoreRuntimeException { } }