diff options
Diffstat (limited to 'sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java')
6 files changed, 642 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/ComponentJavaScriptGenerator.java b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/ComponentJavaScriptGenerator.java new file mode 100644 index 0000000000..d0576b4468 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/ComponentJavaScriptGenerator.java @@ -0,0 +1,60 @@ +/* + * 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.web.javascript; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + + +/** + * Widget component script generator interface + * This generates the necessary JavaScript client code into a single JavaScript per component + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.asclient + */ +public interface ComponentJavaScriptGenerator { + + /** + * Return the QName that identify the Component script generator + * This is used to identify different generators supporting different JavaScript frameworks + * + * @return The QName + */ + QName getQName(); + + /** + * Generate the Java Script code for a given component + * - generate/append client proxyies as needed + * - generate tuscany namespace as needed + * - generate properties for JavaScript injection + * - generate references for JavaScript injection + * + * @param component The SCA Component to be used + * @param pw A Print Writer where the script should be written to + * @throws IOException + */ + void generateJavaScriptCode(RuntimeComponent component, PrintWriter pw) throws IOException; + +} diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/ComponentJavaScriptGeneratorExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/ComponentJavaScriptGeneratorExtensionPoint.java new file mode 100644 index 0000000000..ed42ce0e47 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/ComponentJavaScriptGeneratorExtensionPoint.java @@ -0,0 +1,57 @@ +/* + * 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.web.javascript; + +import java.util.List; + +import javax.xml.namespace.QName; + +/** + * Widget component script generator extension pointinterface + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.asclient + */ +public interface ComponentJavaScriptGeneratorExtensionPoint { + + /** + * Add a component script generator + * @param componentScriptGenerator + */ + void addComponentJavaScriptGenerator(ComponentJavaScriptGenerator componentScriptGenerator); + + /** + * Remove a component script generator + * @param componentScriptGenerator + */ + void removeComponentJavaScriptGenerator(ComponentJavaScriptGenerator componentScriptGenerator); + + /** + * Get a component scrpt generator instance based on QName + * @param bindingName + * @return + */ + ComponentJavaScriptGenerator getComponentJavaScriptGenerator(QName bindingName); + + /** + * Get a list of component script generator instances + */ + List<ComponentJavaScriptGenerator> getComponentJavaScriptGenerators(); +} diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/DefaultComponentJavaScriptGeneratorExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/DefaultComponentJavaScriptGeneratorExtensionPoint.java new file mode 100644 index 0000000000..55326b539e --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/DefaultComponentJavaScriptGeneratorExtensionPoint.java @@ -0,0 +1,158 @@ +/* + * 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.web.javascript; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; + + +/** + * Default extension point for widget component script generator + * + * @version $Rev$ $Date$ + */ +public class DefaultComponentJavaScriptGeneratorExtensionPoint implements ComponentJavaScriptGeneratorExtensionPoint { + private final List<ComponentJavaScriptGenerator> generators = new ArrayList<ComponentJavaScriptGenerator>(); + private final Map<QName, ComponentJavaScriptGenerator> generatorsByQName = new HashMap<QName, ComponentJavaScriptGenerator>(); + + private ExtensionPointRegistry extensionPoints; + private Monitor monitor = null; + + private boolean loaded = false; + + public DefaultComponentJavaScriptGeneratorExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) { + this.monitor = monitorFactory.createMonitor(); + } + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + /* + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + ex); + monitor.problem(problem); + } + */ + } + + public void addComponentJavaScriptGenerator(ComponentJavaScriptGenerator componentScriptGenerator) { + if (componentScriptGenerator.getQName() != null) { + generatorsByQName.put(componentScriptGenerator.getQName(), componentScriptGenerator); + } + + generators.add(componentScriptGenerator); + } + + public void removeComponentJavaScriptGenerator(ComponentJavaScriptGenerator componentScriptGenerator) { + if (componentScriptGenerator.getQName() != null) { + generatorsByQName.remove(componentScriptGenerator.getQName()); + } + + generators.remove(componentScriptGenerator); + } + + + public ComponentJavaScriptGenerator getComponentJavaScriptGenerator(QName bindingName) { + loadFactories(); + return generatorsByQName.get(bindingName); + } + + public List<ComponentJavaScriptGenerator> getComponentJavaScriptGenerators() { + loadFactories(); + return this.generators; + } + + /** + * Private Utility methods + */ + + + /** + * Lazily load artifact processors registered in the extension point. + */ + @SuppressWarnings("unchecked") + private synchronized void loadFactories() { + if (loaded) { + return; + } + + // Get the proxy factories declarations + Collection<ServiceDeclaration> factoryDeclarations = null; + try { + factoryDeclarations = extensionPoints.getServiceDiscovery().getServiceDeclarations(ComponentJavaScriptGenerator.class); + } catch (IOException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", factoryDeclarations, ie); + throw ie; + } + + for (ServiceDeclaration processorDeclaration : factoryDeclarations) { + // Create a factory, and register it + ComponentJavaScriptGenerator generator = null; + try { + Class generatorClass = processorDeclaration.loadClass(); + + Constructor<ComponentJavaScriptGenerator> constructor = generatorClass.getConstructor(ExtensionPointRegistry.class); + generator = constructor.newInstance(extensionPoints); + + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", generator, ie); + throw ie; + } + + addComponentJavaScriptGenerator(generator); + } + + loaded = true; + } + + +} diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/DefaultJavascriptProxyFactoryExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/DefaultJavascriptProxyFactoryExtensionPoint.java new file mode 100644 index 0000000000..402eb53bb0 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/DefaultJavascriptProxyFactoryExtensionPoint.java @@ -0,0 +1,231 @@ +/* + * 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.web.javascript; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; + +/** + * Default extension point for javascript proxy factories + * + * @version $Rev$ $Date$ + */ +public class DefaultJavascriptProxyFactoryExtensionPoint implements JavascriptProxyFactoryExtensionPoint { + private final Map<QName, JavascriptProxyFactory> factoriesByQName = new HashMap<QName, JavascriptProxyFactory>(); + private final Map<Class<?>, JavascriptProxyFactory> factoriesByType = new HashMap<Class<?>, JavascriptProxyFactory>(); + + private Monitor monitor = null; + private ExtensionPointRegistry registry; + private boolean loaded = false; + + public DefaultJavascriptProxyFactoryExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.registry = extensionPoints; + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) { + this.monitor = monitorFactory.createMonitor(); + } + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + /* + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.WARNING, + model, + message, + (Object[])messageParameters); + monitor.problem(problem); + } + */ + } + + public void addProxyFactory(JavascriptProxyFactory javascriptProxyfactory) { + if (javascriptProxyfactory.getModelType() != null) { + factoriesByType.put(javascriptProxyfactory.getModelType(), javascriptProxyfactory); + } + if (javascriptProxyfactory.getQName() != null) { + factoriesByQName.put(javascriptProxyfactory.getQName(), javascriptProxyfactory); + } + } + + public void removeProxyFactory(JavascriptProxyFactory javascriptProxyfactory) { + if (javascriptProxyfactory.getModelType() != null) { + factoriesByType.remove(javascriptProxyfactory.getModelType()); + } + if (javascriptProxyfactory.getQName() != null) { + factoriesByQName.remove(javascriptProxyfactory.getQName()); + } + } + + public JavascriptProxyFactory getProxyFactory(QName bindingName) { + loadFactories(); + return factoriesByQName.get(bindingName); + } + + public JavascriptProxyFactory getProxyFactory(Class<?> bindingType) { + loadFactories(); + Class<?>[] classes = bindingType.getInterfaces(); + for (Class<?> c : classes) { + JavascriptProxyFactory proxyFactory = factoriesByType.get(c); + if (proxyFactory != null) { + return proxyFactory; + } + } + + //here we didn't find the proxy factory for the biding + JavascriptProxyFactory factory = null; + if (bindingType.isInterface()) { + // Dynamically load a factory class declared under META-INF/services + try { + Class<?> factoryClass = registry.getServiceDiscovery().getServiceDeclaration(bindingType).getClass(); + if (factoryClass != null) { + + try { + // Default empty constructor + Constructor<?> constructor = factoryClass.getConstructor(); + factory = (JavascriptProxyFactory) constructor.newInstance(); + } catch (NoSuchMethodException e) { + + // Constructor taking the model factory extension point + Constructor<?> constructor = factoryClass.getConstructor(FactoryExtensionPoint.class); + factory = (JavascriptProxyFactory) constructor.newInstance(this); + } + + // Cache the loaded factory + addProxyFactory(factory); + } + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } else { + + // Call the newInstance static method on the factory abstract class + try { + factory = (JavascriptProxyFactory) ServiceDiscovery.getInstance().getServiceDeclaration(bindingType); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + + // Cache the factory + addProxyFactory(factory); + } + + return factory; + } + + /** + * Private Utility methods + */ + + /** + * Returns a QName object from a QName expressed as {ns}name + * or ns#name. + * + * @param qname + * @return + */ + private static QName getQName(String qname) { + if (qname == null) { + return null; + } + qname = qname.trim(); + if (qname.startsWith("{")) { + int h = qname.indexOf('}'); + if (h != -1) { + return new QName(qname.substring(1, h), qname.substring(h + 1)); + } + } else { + int h = qname.indexOf('#'); + if (h != -1) { + return new QName(qname.substring(0, h), qname.substring(h + 1)); + } + } + throw new IllegalArgumentException("Invalid qname: "+qname); + } + + /** + * Lazily load artifact processors registered in the extension point. + */ + private synchronized void loadFactories() { + if (loaded) { + return; + } + + // Get the proxy factories declarations + Collection<ServiceDeclaration> factoryDeclarations = null; + try { + factoryDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(JavascriptProxyFactory.class); + } catch (IOException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", factoryDeclarations, ie); + throw ie; + } + + for (ServiceDeclaration processorDeclaration : factoryDeclarations) { + Map<String, String> attributes = processorDeclaration.getAttributes(); + + // Load a StAX artifact processor + + // Get the model QName + QName artifactType = getQName(attributes.get("qname")); + + // Get the model class name + String modelTypeName = attributes.get("model"); + + // Create a factory, and register it + JavascriptProxyFactory proxyFactory = null; + try { + proxyFactory = (JavascriptProxyFactory) processorDeclaration.loadClass().newInstance(); + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", proxyFactory, ie); + throw ie; + } + + addProxyFactory(proxyFactory); + } + + loaded = true; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/JavascriptProxyFactory.java b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/JavascriptProxyFactory.java new file mode 100644 index 0000000000..fda093d9aa --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/JavascriptProxyFactory.java @@ -0,0 +1,79 @@ +/* + * 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.web.javascript; + +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.ComponentReference; + +/** + * Javascript Proxy Factory used to allow Web related bindings to generate + * client js proxyies + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.asclient + */ +public interface JavascriptProxyFactory { + + /** + * The binding model type associated with this factory + * @return the binding model type + */ + Class<?> getModelType(); + + /** + * The binding qname associated with this factory + * @return the binding qname + */ + QName getQName(); + + /** + * Get the Javascript proxy client file name + * @return the javascript file name + */ + String getJavascriptProxyFile(); + + /** + * Get the Javascript proxy client contents as a stream + * @return + */ + InputStream getJavascriptProxyFileAsStream() throws IOException; + + /** + * Create any necessary JavaScript imports/headers necessary for the extension to work + * This is useful in case of Dojo that need to generate the requires statements to load the dependencies + * + * @param componentReference + * @return + * @throws IOException + */ + String createJavascriptHeader(ComponentReference componentReference) throws IOException; + + /** + * Create a JavaScript Proxy for a given reference + * @param componentReference The reference + * @return the javascript proxy code + * @throws IOException + */ + String createJavascriptReference(ComponentReference componentReference) throws IOException; +} diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/JavascriptProxyFactoryExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/JavascriptProxyFactoryExtensionPoint.java new file mode 100644 index 0000000000..5856c15a9b --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta1/modules/web-javascript/src/main/java/org/apache/tuscany/sca/web/javascript/JavascriptProxyFactoryExtensionPoint.java @@ -0,0 +1,57 @@ +/* + * 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.web.javascript; + +import javax.xml.namespace.QName; + +/** + * + * @tuscany.spi.extension.asclient + * + */ +public interface JavascriptProxyFactoryExtensionPoint { + /** + * Add Javascript proxy factory + * + * @param javascriptProxyfactory The Javascript proxy factory + */ + void addProxyFactory(JavascriptProxyFactory javascriptProxyfactory); + + /** + * Remove Javascript proxy factory + * + * @param javascriptProxyfactory The Javascript proxy fatory + */ + void removeProxyFactory(JavascriptProxyFactory javascriptProxyfactory); + + /** + * Returns the Javascript proxy factory associated with the given QName + * @param bindingName + * @return + */ + JavascriptProxyFactory getProxyFactory(QName bindingName); + + /** + * Returns the Javascript proxy factory associated with the given Type + * @param bindingType + * @return + */ + JavascriptProxyFactory getProxyFactory(Class<?> bindingType); +} |