blob: d9e4e698e0a5b479af414d0e3a3a5910393e8aeb [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.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("}");
}
}