| /* |
| * 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.widget.dojo; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.PrintWriter; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.apache.tuscany.sca.assembly.Binding; |
| import org.apache.tuscany.sca.assembly.ComponentProperty; |
| import org.apache.tuscany.sca.assembly.ComponentReference; |
| import org.apache.tuscany.sca.assembly.Endpoint; |
| import org.apache.tuscany.sca.assembly.EndpointReference; |
| import org.apache.tuscany.sca.core.ExtensionPointRegistry; |
| import org.apache.tuscany.sca.runtime.RuntimeComponent; |
| import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; |
| import org.apache.tuscany.sca.web.javascript.ComponentJavaScriptGenerator; |
| import org.apache.tuscany.sca.web.javascript.JavascriptProxyFactory; |
| import org.apache.tuscany.sca.web.javascript.JavascriptProxyFactoryExtensionPoint; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| public class DojoJavaScriptComponentGeneratorImpl implements ComponentJavaScriptGenerator { |
| private static final QName NAME = new QName("http://tuscany.apache.org/xmlns/sca/1.1", "component.script.generator.dojo"); |
| |
| private ExtensionPointRegistry extensionPoints; |
| |
| private JavascriptProxyFactoryExtensionPoint javascriptProxyFactories; |
| |
| public DojoJavaScriptComponentGeneratorImpl(ExtensionPointRegistry extensionPoints) { |
| this.extensionPoints = extensionPoints; |
| this.javascriptProxyFactories = extensionPoints.getExtensionPoint(JavascriptProxyFactoryExtensionPoint.class); |
| } |
| |
| public QName getQName() { |
| return NAME; |
| } |
| |
| public void generateJavaScriptCode(RuntimeComponent component, PrintWriter pw) throws IOException { |
| pw.println(); |
| pw.println("/* Apache Tuscany SCA Widget header */"); |
| pw.println(); |
| |
| Map<String, Boolean> bindingClientProcessed = new HashMap<String, Boolean>(); |
| |
| for(ComponentReference reference : component.getReferences()) { |
| for(EndpointReference epr : reference.getEndpointReferences()) { |
| Endpoint targetEndpoint = epr.getTargetEndpoint(); |
| if (targetEndpoint.isUnresolved()) { |
| //force resolution and targetEndpoint binding calculations |
| //by calling the getInvocationChain |
| ((RuntimeEndpointReference) epr).getInvocationChains(); |
| targetEndpoint = epr.getTargetEndpoint(); |
| } |
| |
| Binding binding = targetEndpoint.getBinding(); |
| if (binding != null) { |
| JavascriptProxyFactory jsProxyFactory = javascriptProxyFactories.getProxyFactory(binding.getClass()); |
| |
| String bindingProxyName = jsProxyFactory.getJavascriptProxyFile(); |
| //check if binding client code was already processed and inject to the generated script |
| if(bindingProxyName != null) { |
| Boolean processedFlag = bindingClientProcessed.get(bindingProxyName); |
| if( processedFlag == null || processedFlag.booleanValue() == false) { |
| generateJavaScriptBindingProxy(jsProxyFactory, pw); |
| bindingClientProcessed.put(bindingProxyName, Boolean.TRUE); |
| } |
| } |
| } |
| } |
| } |
| |
| pw.println(); |
| pw.println("/* Tuscany Reference/Property injection code */"); |
| pw.println(); |
| |
| generateJavaScriptHeader(component, javascriptProxyFactories,pw); |
| |
| pw.println(); |
| |
| //define tuscany.sca namespace |
| generateJavaScriptNamespace(pw); |
| |
| pw.println(); |
| |
| //process properties |
| generateJavaScriptPropertyFunction(component, pw); |
| |
| pw.println(); |
| |
| //process references |
| generateJavaScriptReferenceFunction(component, javascriptProxyFactories,pw); |
| |
| |
| pw.println(); |
| pw.println("/** End of Apache Tuscany SCA Widget */"); |
| pw.println(); |
| pw.flush(); |
| pw.close(); |
| } |
| |
| |
| /** |
| * Retrieve the binding proxy based on the bind name |
| * and embedded the JavaScript into this js |
| */ |
| private static void generateJavaScriptBindingProxy(JavascriptProxyFactory javascriptProxyFactory, PrintWriter pw) throws IOException { |
| InputStream is = javascriptProxyFactory.getJavascriptProxyFileAsStream(); |
| if (is != null) { |
| int i; |
| while ((i = is.read()) != -1) { |
| pw.write(i); |
| } |
| } |
| |
| pw.println(); |
| pw.println(); |
| } |
| |
| /** |
| * |
| * @param pw |
| * @throws IOException |
| */ |
| private static void generateJavaScriptHeader(RuntimeComponent component, JavascriptProxyFactoryExtensionPoint javascriptProxyFactories, PrintWriter pw) throws IOException { |
| Map<String, Boolean> bindingHeaderProcessed = new HashMap<String, Boolean>(); |
| |
| for(ComponentReference reference : component.getReferences()) { |
| for(EndpointReference epr : reference.getEndpointReferences()) { |
| Endpoint targetEndpoint = epr.getTargetEndpoint(); |
| if (targetEndpoint.isUnresolved()) { |
| //force resolution and targetEndpoint binding calculations |
| //by calling the getInvocationChain |
| ((RuntimeEndpointReference) epr).getInvocationChains(); |
| targetEndpoint = epr.getTargetEndpoint(); |
| } |
| |
| Binding binding = targetEndpoint.getBinding(); |
| if (binding != null) { |
| JavascriptProxyFactory jsProxyFactory = javascriptProxyFactories.getProxyFactory(binding.getClass()); |
| |
| String bindingKey = binding.getClass().getName(); |
| Boolean processedFlag = bindingHeaderProcessed.get(bindingKey); |
| |
| //check if binding client code was already processed and inject to the generated script |
| if( processedFlag == null || processedFlag.booleanValue() == false) { |
| pw.println(jsProxyFactory.createJavascriptHeader(reference)); |
| bindingHeaderProcessed.put(bindingKey, Boolean.TRUE); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| /** |
| * Generate the tuscany.sca namespace if not yet available |
| * @param pw |
| * @throws IOException |
| */ |
| private static void generateJavaScriptNamespace(PrintWriter pw) throws IOException { |
| pw.println("if (!window.tuscany) { \n" + |
| "window.tuscany = {}; \n" + |
| "}"); |
| pw.println("var __tuscany = window.tuscany;"); |
| |
| pw.println("if (!__tuscany.sca) { \n" + |
| "__tuscany.sca = {}; \n" + |
| "}"); |
| } |
| |
| |
| /** |
| * Generate JavaScript code to inject SCA Properties |
| * @param pw |
| * @throws IOException |
| */ |
| private static void generateJavaScriptPropertyFunction(RuntimeComponent component, PrintWriter pw) throws IOException { |
| pw.println("__tuscany.sca.propertyMap = {};"); |
| for(ComponentProperty property : component.getProperties()) { |
| String propertyName = property.getName(); |
| |
| pw.println("__tuscany.sca.propertyMap." + propertyName + " = new String(\"" + getPropertyValue(property) + "\");"); |
| } |
| |
| pw.println("tuscany.sca.Property = function (name) {"); |
| pw.println(" return __tuscany.sca.propertyMap[name];"); |
| pw.println("}"); |
| } |
| |
| /** |
| * Convert property value to String |
| * @param property |
| * @return |
| */ |
| private static String getPropertyValue(ComponentProperty property) { |
| Document doc = (Document)property.getValue(); |
| Element rootElement = doc.getDocumentElement(); |
| |
| String value = null; |
| |
| //FIXME : Provide support for isMany and other property types |
| |
| if (rootElement.getChildNodes().getLength() > 0) { |
| value = rootElement.getChildNodes().item(0).getTextContent(); |
| } |
| |
| return value; |
| } |
| |
| |
| |
| /** |
| * Generate JavaScript code to inject SCA References |
| * @param pw |
| * @throws IOException |
| */ |
| private static void generateJavaScriptReferenceFunction (RuntimeComponent component, JavascriptProxyFactoryExtensionPoint javascriptProxyFactories, PrintWriter pw) throws IOException { |
| |
| pw.println("__tuscany.sca.referenceMap = {};"); |
| for(ComponentReference reference : component.getReferences()) { |
| for(EndpointReference epr : reference.getEndpointReferences()) { |
| Endpoint targetEndpoint = epr.getTargetEndpoint(); |
| if (targetEndpoint.isUnresolved()) { |
| //force resolution and targetEndpoint binding calculations |
| //by calling the getInvocationChain |
| ((RuntimeEndpointReference) epr).getInvocationChains(); |
| targetEndpoint = epr.getTargetEndpoint(); |
| } |
| |
| Binding binding = targetEndpoint.getBinding(); |
| if (binding != null) { |
| String referenceName = reference.getName(); |
| JavascriptProxyFactory jsProxyFactory = javascriptProxyFactories.getProxyFactory(binding.getClass()); |
| |
| pw.println("__tuscany.sca.referenceMap." + referenceName + " = new " + jsProxyFactory.createJavascriptReference(reference) + ";"); |
| } |
| } |
| } |
| |
| pw.println("tuscany.sca.Reference = function (name) {"); |
| pw.println(" return __tuscany.sca.referenceMap[name];"); |
| pw.println("}"); |
| } |
| |
| } |