123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*
- @VaadinApache2LicenseForJavaFiles@
- */
-
- package com.vaadin.terminal.gwt.widgetsetutils;
-
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.Set;
-
- import com.google.gwt.core.client.GWT;
- import com.google.gwt.core.ext.Generator;
- import com.google.gwt.core.ext.GeneratorContext;
- import com.google.gwt.core.ext.TreeLogger;
- import com.google.gwt.core.ext.TreeLogger.Type;
- import com.google.gwt.core.ext.UnableToCompleteException;
- import com.google.gwt.core.ext.typeinfo.JClassType;
- import com.google.gwt.core.ext.typeinfo.NotFoundException;
- import com.google.gwt.core.ext.typeinfo.TypeOracle;
- import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
- import com.google.gwt.user.rebind.SourceWriter;
- import com.vaadin.shared.communication.ClientRpc;
- import com.vaadin.shared.communication.ServerRpc;
- import com.vaadin.shared.ui.Connect;
- import com.vaadin.shared.ui.Connect.LoadStyle;
- import com.vaadin.terminal.gwt.client.ServerConnector;
- import com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader;
- import com.vaadin.terminal.gwt.client.metadata.TypeDataBundle;
- import com.vaadin.terminal.gwt.client.metadata.TypeDataStore;
- import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorBundle;
- import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorInitVisitor;
- import com.vaadin.terminal.gwt.widgetsetutils.metadata.TypeVisitor;
-
- public class ConnectorBundleLoaderFactory extends Generator {
-
- @Override
- public String generate(TreeLogger logger, GeneratorContext context,
- String typeName) throws UnableToCompleteException {
- TypeOracle typeOracle = context.getTypeOracle();
-
- try {
- JClassType classType = typeOracle.getType(typeName);
- String packageName = classType.getPackage().getName();
- String className = classType.getSimpleSourceName() + "Impl";
-
- generateClass(logger, context, packageName, className, typeName);
-
- return packageName + "." + className;
- } catch (UnableToCompleteException e) {
- // Just rethrow
- throw e;
- } catch (Exception e) {
- logger.log(Type.ERROR, getClass() + " failed", e);
- throw new UnableToCompleteException();
- }
-
- }
-
- private void generateClass(TreeLogger logger, GeneratorContext context,
- String packageName, String className, String requestedType)
- throws Exception {
- PrintWriter printWriter = context.tryCreate(logger, packageName,
- className);
- if (printWriter == null) {
- return;
- }
-
- List<ConnectorBundle> bundles = buildBundles(logger,
- context.getTypeOracle());
-
- ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(
- packageName, className);
- composer.setSuperclass(requestedType);
-
- SourceWriter w = composer.createSourceWriter(context, printWriter);
-
- w.println("public void init() {");
- w.indent();
-
- for (ConnectorBundle bundle : bundles) {
- String name = bundle.getName();
- boolean isEager = name
- .equals(ConnectorBundleLoader.EAGER_BUNDLE_NAME);
-
- w.print("addAsyncBlockLoader(new AsyncBundleLoader(\"");
- w.print(escape(name));
- w.print("\", ");
-
- w.print("new String[] {");
- for (Entry<JClassType, Set<String>> entry : bundle.getIdentifiers()
- .entrySet()) {
- Set<String> identifiers = entry.getValue();
- for (String id : identifiers) {
- w.print("\"");
- w.print(escape(id));
- w.print("\",");
- }
- }
- w.println("}) {");
- w.indent();
-
- w.print("protected void load(final ");
- w.print(TypeDataStore.class.getName());
- w.println(" store) {");
- w.indent();
-
- if (!isEager) {
- w.print(GWT.class.getName());
- w.print(".runAsync(");
- }
-
- w.print("new ");
- w.print(TypeDataBundle.class.getName());
- w.println("(getName()) {");
- w.indent();
-
- w.println("public void load() {");
- w.indent();
-
- printBundleData(w, bundle);
-
- // Close load method
- w.outdent();
- w.println("}");
-
- // Close new TypeDataBundle() {}
- w.outdent();
- w.print("}");
-
- if (isEager) {
- w.println(".onSuccess();");
- } else {
- w.println(");");
- }
-
- // Close load method
- w.outdent();
- w.println("}");
-
- // Close add(new ...
- w.outdent();
- w.println("});");
- }
-
- w.outdent();
- w.println("}");
-
- w.commit(logger);
- }
-
- private void printBundleData(SourceWriter w, ConnectorBundle bundle) {
- writeIdentifiers(w, bundle);
- writeGwtConstructors(w, bundle);
- }
-
- private void writeGwtConstructors(SourceWriter w, ConnectorBundle bundle) {
- Set<JClassType> constructors = bundle.getGwtConstructors();
- for (JClassType type : constructors) {
- w.print("store.setConstructor(");
- printClassLiteral(w, type);
- w.print(", new Invoker() {");
- w.indent();
-
- w.println("public Object invoke(Object target, Object[] params) {");
- w.indent();
-
- w.print("return ");
- w.print(GWT.class.getName());
- w.print(".create(");
- printClassLiteral(w, type);
- w.println(");");
-
- w.outdent();
- w.println("}");
-
- w.outdent();
- w.println("});");
- }
- }
-
- private void printClassLiteral(SourceWriter w, JClassType type) {
- w.print(type.getQualifiedSourceName());
- w.print(".class");
- }
-
- private void writeIdentifiers(SourceWriter w, ConnectorBundle bundle) {
- Map<JClassType, Set<String>> identifiers = bundle.getIdentifiers();
- for (Entry<JClassType, Set<String>> entry : identifiers.entrySet()) {
- Set<String> ids = entry.getValue();
- JClassType type = entry.getKey();
- for (String id : ids) {
- w.print("store.setClass(\"");
- w.print(escape(id));
- w.print("\", ");
- printClassLiteral(w, type);
- w.println(");");
- }
- }
- }
-
- private List<ConnectorBundle> buildBundles(TreeLogger logger,
- TypeOracle typeOracle) throws NotFoundException {
-
- Map<LoadStyle, Collection<JClassType>> connectorsByLoadStyle = new HashMap<LoadStyle, Collection<JClassType>>();
- for (LoadStyle loadStyle : LoadStyle.values()) {
- connectorsByLoadStyle.put(loadStyle, new ArrayList<JClassType>());
- }
-
- JClassType connectorType = typeOracle.getType(ServerConnector.class
- .getName());
- JClassType[] subtypes = connectorType.getSubtypes();
- for (JClassType connectorSubtype : subtypes) {
- if (!connectorSubtype.isAnnotationPresent(Connect.class)) {
- continue;
- }
- LoadStyle loadStyle = getLoadStyle(connectorSubtype);
- if (loadStyle != null) {
- connectorsByLoadStyle.get(loadStyle).add(connectorSubtype);
- }
- }
-
- List<ConnectorBundle> bundles = new ArrayList<ConnectorBundle>();
-
- Collection<TypeVisitor> visitors = getVisitors(typeOracle);
-
- ConnectorBundle eagerBundle = new ConnectorBundle(
- ConnectorBundleLoader.EAGER_BUNDLE_NAME, null);
-
- // Eager connectors and all RPC interfaces are loaded by default
- eagerBundle.visitTypes(connectorsByLoadStyle.get(LoadStyle.EAGER),
- visitors);
- eagerBundle.visitSubTypes(
- typeOracle.getType(ClientRpc.class.getName()), visitors);
- eagerBundle.visitSubTypes(
- typeOracle.getType(ServerRpc.class.getName()), visitors);
-
- bundles.add(eagerBundle);
-
- ConnectorBundle deferredBundle = new ConnectorBundle(
- ConnectorBundleLoader.DEFERRED_BUNDLE_NAME, eagerBundle);
- deferredBundle.visitTypes(
- connectorsByLoadStyle.get(LoadStyle.DEFERRED), visitors);
-
- bundles.add(deferredBundle);
-
- Collection<JClassType> lazy = connectorsByLoadStyle.get(LoadStyle.LAZY);
- for (JClassType type : lazy) {
- ConnectorBundle bundle = new ConnectorBundle(type.getName(),
- deferredBundle);
- bundle.visitTypes(Collections.singleton(type), visitors);
-
- bundles.add(bundle);
- }
-
- return bundles;
- }
-
- private Collection<TypeVisitor> getVisitors(TypeOracle oracle)
- throws NotFoundException {
- List<TypeVisitor> visitors = Arrays
- .<TypeVisitor> asList(new ConnectorInitVisitor());
- for (TypeVisitor typeVisitor : visitors) {
- typeVisitor.init(oracle);
- }
- return visitors;
- }
-
- protected LoadStyle getLoadStyle(JClassType connectorType) {
- Connect annotation = connectorType.getAnnotation(Connect.class);
- return annotation.loadStyle();
- }
-
- }
|