You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConnectorBundleLoaderFactory.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.widgetsetutils;
  5. import java.io.PrintWriter;
  6. import java.util.ArrayList;
  7. import java.util.Arrays;
  8. import java.util.Collection;
  9. import java.util.HashMap;
  10. import java.util.HashSet;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.Map.Entry;
  14. import java.util.Set;
  15. import com.google.gwt.core.client.GWT;
  16. import com.google.gwt.core.ext.Generator;
  17. import com.google.gwt.core.ext.GeneratorContext;
  18. import com.google.gwt.core.ext.TreeLogger;
  19. import com.google.gwt.core.ext.TreeLogger.Type;
  20. import com.google.gwt.core.ext.UnableToCompleteException;
  21. import com.google.gwt.core.ext.typeinfo.JClassType;
  22. import com.google.gwt.core.ext.typeinfo.JMethod;
  23. import com.google.gwt.core.ext.typeinfo.JParameterizedType;
  24. import com.google.gwt.core.ext.typeinfo.JType;
  25. import com.google.gwt.core.ext.typeinfo.NotFoundException;
  26. import com.google.gwt.core.ext.typeinfo.TypeOracle;
  27. import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
  28. import com.google.gwt.user.rebind.SourceWriter;
  29. import com.vaadin.client.ServerConnector;
  30. import com.vaadin.client.metadata.ConnectorBundleLoader;
  31. import com.vaadin.client.metadata.InvokationHandler;
  32. import com.vaadin.client.metadata.ProxyHandler;
  33. import com.vaadin.client.metadata.TypeData;
  34. import com.vaadin.client.metadata.TypeDataBundle;
  35. import com.vaadin.client.metadata.TypeDataStore;
  36. import com.vaadin.client.ui.UnknownComponentConnector;
  37. import com.vaadin.shared.annotations.Delayed;
  38. import com.vaadin.shared.annotations.DelegateToWidget;
  39. import com.vaadin.shared.communication.ClientRpc;
  40. import com.vaadin.shared.communication.ServerRpc;
  41. import com.vaadin.shared.ui.Connect;
  42. import com.vaadin.shared.ui.Connect.LoadStyle;
  43. import com.vaadin.terminal.gwt.widgetsetutils.metadata.ClientRpcVisitor;
  44. import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorBundle;
  45. import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorInitVisitor;
  46. import com.vaadin.terminal.gwt.widgetsetutils.metadata.GeneratedSerializer;
  47. import com.vaadin.terminal.gwt.widgetsetutils.metadata.Property;
  48. import com.vaadin.terminal.gwt.widgetsetutils.metadata.ServerRpcVisitor;
  49. import com.vaadin.terminal.gwt.widgetsetutils.metadata.StateInitVisitor;
  50. import com.vaadin.terminal.gwt.widgetsetutils.metadata.TypeVisitor;
  51. import com.vaadin.terminal.gwt.widgetsetutils.metadata.WidgetInitVisitor;
  52. public class ConnectorBundleLoaderFactory extends Generator {
  53. @Override
  54. public String generate(TreeLogger logger, GeneratorContext context,
  55. String typeName) throws UnableToCompleteException {
  56. TypeOracle typeOracle = context.getTypeOracle();
  57. try {
  58. JClassType classType = typeOracle.getType(typeName);
  59. String packageName = classType.getPackage().getName();
  60. String className = classType.getSimpleSourceName() + "Impl";
  61. generateClass(logger, context, packageName, className, typeName);
  62. return packageName + "." + className;
  63. } catch (UnableToCompleteException e) {
  64. // Just rethrow
  65. throw e;
  66. } catch (Exception e) {
  67. logger.log(Type.ERROR, getClass() + " failed", e);
  68. throw new UnableToCompleteException();
  69. }
  70. }
  71. private void generateClass(TreeLogger logger, GeneratorContext context,
  72. String packageName, String className, String requestedType)
  73. throws Exception {
  74. PrintWriter printWriter = context.tryCreate(logger, packageName,
  75. className);
  76. if (printWriter == null) {
  77. return;
  78. }
  79. List<ConnectorBundle> bundles = buildBundles(logger,
  80. context.getTypeOracle());
  81. ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(
  82. packageName, className);
  83. composer.setSuperclass(requestedType);
  84. SourceWriter w = composer.createSourceWriter(context, printWriter);
  85. w.println("public void init() {");
  86. w.indent();
  87. for (ConnectorBundle bundle : bundles) {
  88. String name = bundle.getName();
  89. boolean isEager = name
  90. .equals(ConnectorBundleLoader.EAGER_BUNDLE_NAME);
  91. w.print("addAsyncBlockLoader(new AsyncBundleLoader(\"");
  92. w.print(escape(name));
  93. w.print("\", ");
  94. w.print("new String[] {");
  95. for (Entry<JClassType, Set<String>> entry : bundle.getIdentifiers()
  96. .entrySet()) {
  97. Set<String> identifiers = entry.getValue();
  98. for (String id : identifiers) {
  99. w.print("\"");
  100. w.print(escape(id));
  101. w.print("\",");
  102. }
  103. }
  104. w.println("}) {");
  105. w.indent();
  106. w.print("protected void load(final ");
  107. w.print(TypeDataStore.class.getName());
  108. w.println(" store) {");
  109. w.indent();
  110. if (!isEager) {
  111. w.print(GWT.class.getName());
  112. w.print(".runAsync(");
  113. }
  114. w.print("new ");
  115. w.print(TypeDataBundle.class.getName());
  116. w.println("(getName()) {");
  117. w.indent();
  118. w.println("public void load() {");
  119. w.indent();
  120. printBundleData(logger, w, bundle);
  121. // Close load method
  122. w.outdent();
  123. w.println("}");
  124. // Close new TypeDataBundle() {}
  125. w.outdent();
  126. w.print("}");
  127. if (isEager) {
  128. w.println(".onSuccess();");
  129. } else {
  130. w.println(");");
  131. }
  132. // Close load method
  133. w.outdent();
  134. w.println("}");
  135. // Close add(new ...
  136. w.outdent();
  137. w.println("});");
  138. }
  139. w.outdent();
  140. w.println("}");
  141. w.commit(logger);
  142. }
  143. private void printBundleData(TreeLogger logger, SourceWriter w,
  144. ConnectorBundle bundle) throws UnableToCompleteException {
  145. writeIdentifiers(w, bundle);
  146. writeGwtConstructors(w, bundle);
  147. writeReturnTypes(w, bundle);
  148. writeInvokers(w, bundle);
  149. writeParamTypes(w, bundle);
  150. writeProxys(w, bundle);
  151. wirteDelayedInfo(w, bundle);
  152. writeProperites(logger, w, bundle);
  153. writePropertyTypes(w, bundle);
  154. writeSetters(logger, w, bundle);
  155. writeGetters(logger, w, bundle);
  156. writeSerializers(logger, w, bundle);
  157. writeDelegateToWidget(logger, w, bundle);
  158. }
  159. private void writeDelegateToWidget(TreeLogger logger, SourceWriter w,
  160. ConnectorBundle bundle) {
  161. Set<Property> needsDelegateToWidget = bundle.getNeedsDelegateToWidget();
  162. for (Property property : needsDelegateToWidget) {
  163. w.println("store.setDelegateToWidget(%s, \"%s\", \"%s\");",
  164. getClassLiteralString(property.getBeanType()),
  165. property.getName(),
  166. property.getAnnotation(DelegateToWidget.class).value());
  167. }
  168. }
  169. private void writeSerializers(TreeLogger logger, SourceWriter w,
  170. ConnectorBundle bundle) throws UnableToCompleteException {
  171. Map<JType, GeneratedSerializer> serializers = bundle.getSerializers();
  172. for (Entry<JType, GeneratedSerializer> entry : serializers.entrySet()) {
  173. JType type = entry.getKey();
  174. GeneratedSerializer serializer = entry.getValue();
  175. w.print("store.setSerializerFactory(");
  176. writeClassLiteral(w, type);
  177. w.print(", ");
  178. w.println("new Invoker() {");
  179. w.indent();
  180. w.println("public Object invoke(Object target, Object[] params) {");
  181. w.indent();
  182. serializer.writeSerializerInstantiator(logger, w);
  183. w.outdent();
  184. w.println("}");
  185. w.outdent();
  186. w.print("}");
  187. w.println(");");
  188. }
  189. }
  190. private void writeGetters(TreeLogger logger, SourceWriter w,
  191. ConnectorBundle bundle) {
  192. Set<Property> properties = bundle.getNeedsSetter();
  193. for (Property property : properties) {
  194. w.print("store.setGetter(");
  195. writeClassLiteral(w, property.getBeanType());
  196. w.print(", \"");
  197. w.print(escape(property.getName()));
  198. w.println("\", new Invoker() {");
  199. w.indent();
  200. w.println("public Object invoke(Object bean, Object[] params) {");
  201. w.indent();
  202. property.writeGetterBody(logger, w, "bean");
  203. w.println();
  204. w.outdent();
  205. w.println("}");
  206. w.outdent();
  207. w.println("});");
  208. }
  209. }
  210. private void writeSetters(TreeLogger logger, SourceWriter w,
  211. ConnectorBundle bundle) {
  212. Set<Property> properties = bundle.getNeedsSetter();
  213. for (Property property : properties) {
  214. w.print("store.setSetter(");
  215. writeClassLiteral(w, property.getBeanType());
  216. w.print(", \"");
  217. w.print(escape(property.getName()));
  218. w.println("\", new Invoker() {");
  219. w.indent();
  220. w.println("public Object invoke(Object bean, Object[] params) {");
  221. w.indent();
  222. property.writeSetterBody(logger, w, "bean", "params[0]");
  223. w.println("return null;");
  224. w.outdent();
  225. w.println("}");
  226. w.outdent();
  227. w.println("});");
  228. }
  229. }
  230. private void writePropertyTypes(SourceWriter w, ConnectorBundle bundle) {
  231. Set<Property> properties = bundle.getNeedsType();
  232. for (Property property : properties) {
  233. w.print("store.setPropertyType(");
  234. writeClassLiteral(w, property.getBeanType());
  235. w.print(", \"");
  236. w.print(escape(property.getName()));
  237. w.print("\", ");
  238. writeTypeCreator(w, property.getPropertyType());
  239. w.println(");");
  240. }
  241. }
  242. private void writeProperites(TreeLogger logger, SourceWriter w,
  243. ConnectorBundle bundle) throws UnableToCompleteException {
  244. Set<JClassType> needsPropertyListing = bundle.getNeedsPropertyListing();
  245. for (JClassType type : needsPropertyListing) {
  246. w.print("store.setProperties(");
  247. writeClassLiteral(w, type);
  248. w.print(", new String[] {");
  249. Set<String> usedPropertyNames = new HashSet<String>();
  250. Collection<Property> properties = bundle.getProperties(type);
  251. for (Property property : properties) {
  252. String name = property.getName();
  253. if (!usedPropertyNames.add(name)) {
  254. logger.log(
  255. Type.ERROR,
  256. type.getQualifiedSourceName()
  257. + " has multiple properties with the name "
  258. + name
  259. + ". This can happen if there are multiple setters with identical names exect casing.");
  260. throw new UnableToCompleteException();
  261. }
  262. w.print("\"");
  263. w.print(name);
  264. w.print("\", ");
  265. }
  266. w.println("});");
  267. }
  268. }
  269. private void wirteDelayedInfo(SourceWriter w, ConnectorBundle bundle) {
  270. Map<JClassType, Set<JMethod>> needsDelayedInfo = bundle
  271. .getNeedsDelayedInfo();
  272. Set<Entry<JClassType, Set<JMethod>>> entrySet = needsDelayedInfo
  273. .entrySet();
  274. for (Entry<JClassType, Set<JMethod>> entry : entrySet) {
  275. JClassType type = entry.getKey();
  276. Set<JMethod> methods = entry.getValue();
  277. for (JMethod method : methods) {
  278. Delayed annotation = method.getAnnotation(Delayed.class);
  279. if (annotation != null) {
  280. w.print("store.setDelayed(");
  281. writeClassLiteral(w, type);
  282. w.print(", \"");
  283. w.print(escape(method.getName()));
  284. w.println("\");");
  285. if (annotation.lastonly()) {
  286. w.print("store.setLastonly(");
  287. writeClassLiteral(w, type);
  288. w.print(", \"");
  289. w.print(escape(method.getName()));
  290. w.println("\");");
  291. }
  292. }
  293. }
  294. }
  295. }
  296. private void writeProxys(SourceWriter w, ConnectorBundle bundle) {
  297. Set<JClassType> needsProxySupport = bundle.getNeedsProxySupport();
  298. for (JClassType type : needsProxySupport) {
  299. w.print("store.setProxyHandler(");
  300. writeClassLiteral(w, type);
  301. w.print(", new ");
  302. w.print(ProxyHandler.class.getCanonicalName());
  303. w.println("() {");
  304. w.indent();
  305. w.println("public Object createProxy(final "
  306. + InvokationHandler.class.getName() + " handler) {");
  307. w.indent();
  308. w.print("return new ");
  309. w.print(type.getQualifiedSourceName());
  310. w.println("() {");
  311. w.indent();
  312. JMethod[] methods = type.getOverridableMethods();
  313. for (JMethod method : methods) {
  314. if (method.isAbstract()) {
  315. w.print("public ");
  316. w.print(method.getReturnType().getQualifiedSourceName());
  317. w.print(" ");
  318. w.print(method.getName());
  319. w.print("(");
  320. JType[] types = method.getParameterTypes();
  321. for (int i = 0; i < types.length; i++) {
  322. if (i != 0) {
  323. w.print(", ");
  324. }
  325. w.print(types[i].getQualifiedSourceName());
  326. w.print(" p");
  327. w.print(Integer.toString(i));
  328. }
  329. w.println(") {");
  330. w.indent();
  331. if (!method.getReturnType().getQualifiedSourceName()
  332. .equals("void")) {
  333. w.print("return ");
  334. }
  335. w.print("handler.invoke(this, ");
  336. w.print(TypeData.class.getCanonicalName());
  337. w.print(".getType(");
  338. writeClassLiteral(w, type);
  339. w.print(").getMethod(\"");
  340. w.print(escape(method.getName()));
  341. w.print("\"), new Object [] {");
  342. for (int i = 0; i < types.length; i++) {
  343. w.print("p" + i + ", ");
  344. }
  345. w.println("});");
  346. w.outdent();
  347. w.println("}");
  348. }
  349. }
  350. w.outdent();
  351. w.println("};");
  352. w.outdent();
  353. w.println("}");
  354. w.outdent();
  355. w.println("});");
  356. }
  357. }
  358. private void writeParamTypes(SourceWriter w, ConnectorBundle bundle) {
  359. Map<JClassType, Set<JMethod>> needsParamTypes = bundle
  360. .getNeedsParamTypes();
  361. for (Entry<JClassType, Set<JMethod>> entry : needsParamTypes.entrySet()) {
  362. JClassType type = entry.getKey();
  363. Set<JMethod> methods = entry.getValue();
  364. for (JMethod method : methods) {
  365. w.print("store.setParamTypes(");
  366. writeClassLiteral(w, type);
  367. w.print(", \"");
  368. w.print(escape(method.getName()));
  369. w.print("\", new Type[] {");
  370. for (JType parameter : method.getParameterTypes()) {
  371. ConnectorBundleLoaderFactory.writeTypeCreator(w, parameter);
  372. w.print(", ");
  373. }
  374. w.println("});");
  375. }
  376. }
  377. }
  378. private void writeInvokers(SourceWriter w, ConnectorBundle bundle) {
  379. Map<JClassType, Set<JMethod>> needsInvoker = bundle.getNeedsInvoker();
  380. for (Entry<JClassType, Set<JMethod>> entry : needsInvoker.entrySet()) {
  381. JClassType type = entry.getKey();
  382. Set<JMethod> methods = entry.getValue();
  383. for (JMethod method : methods) {
  384. w.print("store.setInvoker(");
  385. writeClassLiteral(w, type);
  386. w.print(", \"");
  387. w.print(escape(method.getName()));
  388. w.println("\", new Invoker() {");
  389. w.indent();
  390. w.println("public Object invoke(Object target, Object[] params) {");
  391. w.indent();
  392. JType returnType = method.getReturnType();
  393. boolean hasReturnType = !"void".equals(returnType
  394. .getQualifiedSourceName());
  395. if (hasReturnType) {
  396. w.print("return ");
  397. }
  398. JType[] parameterTypes = method.getParameterTypes();
  399. w.print("((" + type.getQualifiedSourceName() + ") target)."
  400. + method.getName() + "(");
  401. for (int i = 0; i < parameterTypes.length; i++) {
  402. JType parameterType = parameterTypes[i];
  403. if (i != 0) {
  404. w.print(", ");
  405. }
  406. String parameterTypeName = getBoxedTypeName(parameterType);
  407. w.print("(" + parameterTypeName + ") params[" + i + "]");
  408. }
  409. w.println(");");
  410. if (!hasReturnType) {
  411. w.println("return null;");
  412. }
  413. w.outdent();
  414. w.println("}");
  415. w.outdent();
  416. w.println("});");
  417. }
  418. }
  419. }
  420. private void writeReturnTypes(SourceWriter w, ConnectorBundle bundle) {
  421. Map<JClassType, Set<JMethod>> methodReturnTypes = bundle
  422. .getMethodReturnTypes();
  423. for (Entry<JClassType, Set<JMethod>> entry : methodReturnTypes
  424. .entrySet()) {
  425. JClassType type = entry.getKey();
  426. Set<JMethod> methods = entry.getValue();
  427. for (JMethod method : methods) {
  428. // setReturnType(Class<?> type, String methodName, Type
  429. // returnType)
  430. w.print("store.setReturnType(");
  431. writeClassLiteral(w, type);
  432. w.print(", \"");
  433. w.print(escape(method.getName()));
  434. w.print("\", ");
  435. writeTypeCreator(w, method.getReturnType());
  436. w.println(");");
  437. }
  438. }
  439. }
  440. private void writeGwtConstructors(SourceWriter w, ConnectorBundle bundle) {
  441. Set<JClassType> constructors = bundle.getGwtConstructors();
  442. for (JClassType type : constructors) {
  443. w.print("store.setConstructor(");
  444. writeClassLiteral(w, type);
  445. w.println(", new Invoker() {");
  446. w.indent();
  447. w.println("public Object invoke(Object target, Object[] params) {");
  448. w.indent();
  449. w.print("return ");
  450. w.print(GWT.class.getName());
  451. w.print(".create(");
  452. writeClassLiteral(w, type);
  453. w.println(");");
  454. w.outdent();
  455. w.println("}");
  456. w.outdent();
  457. w.println("});");
  458. }
  459. }
  460. public static void writeClassLiteral(SourceWriter w, JType type) {
  461. w.print(getClassLiteralString(type));
  462. }
  463. public static String getClassLiteralString(JType type) {
  464. return type.getQualifiedSourceName() + ".class";
  465. }
  466. private void writeIdentifiers(SourceWriter w, ConnectorBundle bundle) {
  467. Map<JClassType, Set<String>> identifiers = bundle.getIdentifiers();
  468. for (Entry<JClassType, Set<String>> entry : identifiers.entrySet()) {
  469. Set<String> ids = entry.getValue();
  470. JClassType type = entry.getKey();
  471. for (String id : ids) {
  472. w.print("store.setClass(\"");
  473. w.print(escape(id));
  474. w.print("\", ");
  475. writeClassLiteral(w, type);
  476. w.println(");");
  477. }
  478. }
  479. }
  480. private List<ConnectorBundle> buildBundles(TreeLogger logger,
  481. TypeOracle typeOracle) throws NotFoundException,
  482. UnableToCompleteException {
  483. Map<LoadStyle, Collection<JClassType>> connectorsByLoadStyle = new HashMap<LoadStyle, Collection<JClassType>>();
  484. for (LoadStyle loadStyle : LoadStyle.values()) {
  485. connectorsByLoadStyle.put(loadStyle, new ArrayList<JClassType>());
  486. }
  487. JClassType connectorType = typeOracle.getType(ServerConnector.class
  488. .getName());
  489. JClassType[] subtypes = connectorType.getSubtypes();
  490. for (JClassType connectorSubtype : subtypes) {
  491. if (!connectorSubtype.isAnnotationPresent(Connect.class)) {
  492. continue;
  493. }
  494. LoadStyle loadStyle = getLoadStyle(connectorSubtype);
  495. if (loadStyle != null) {
  496. connectorsByLoadStyle.get(loadStyle).add(connectorSubtype);
  497. }
  498. }
  499. List<ConnectorBundle> bundles = new ArrayList<ConnectorBundle>();
  500. Collection<TypeVisitor> visitors = getVisitors(typeOracle);
  501. ConnectorBundle eagerBundle = new ConnectorBundle(
  502. ConnectorBundleLoader.EAGER_BUNDLE_NAME, visitors, typeOracle);
  503. TreeLogger eagerLogger = logger.branch(Type.TRACE,
  504. "Populating eager bundle");
  505. // Eager connectors and all RPC interfaces are loaded by default
  506. eagerBundle.processTypes(eagerLogger,
  507. connectorsByLoadStyle.get(LoadStyle.EAGER));
  508. eagerBundle.processType(eagerLogger, typeOracle
  509. .findType(UnknownComponentConnector.class.getCanonicalName()));
  510. eagerBundle.processSubTypes(eagerLogger,
  511. typeOracle.getType(ClientRpc.class.getName()));
  512. eagerBundle.processSubTypes(eagerLogger,
  513. typeOracle.getType(ServerRpc.class.getName()));
  514. bundles.add(eagerBundle);
  515. ConnectorBundle deferredBundle = new ConnectorBundle(
  516. ConnectorBundleLoader.DEFERRED_BUNDLE_NAME, eagerBundle);
  517. TreeLogger deferredLogger = logger.branch(Type.TRACE,
  518. "Populating deferred bundle");
  519. deferredBundle.processTypes(deferredLogger,
  520. connectorsByLoadStyle.get(LoadStyle.DEFERRED));
  521. bundles.add(deferredBundle);
  522. Collection<JClassType> lazy = connectorsByLoadStyle.get(LoadStyle.LAZY);
  523. for (JClassType type : lazy) {
  524. ConnectorBundle bundle = new ConnectorBundle(type.getName(),
  525. eagerBundle);
  526. TreeLogger subLogger = logger.branch(Type.TRACE, "Populating "
  527. + type.getName() + " bundle");
  528. bundle.processType(subLogger, type);
  529. bundles.add(bundle);
  530. }
  531. return bundles;
  532. }
  533. private Collection<TypeVisitor> getVisitors(TypeOracle oracle)
  534. throws NotFoundException {
  535. List<TypeVisitor> visitors = Arrays.<TypeVisitor> asList(
  536. new ConnectorInitVisitor(), new StateInitVisitor(),
  537. new WidgetInitVisitor(), new ClientRpcVisitor(),
  538. new ServerRpcVisitor());
  539. for (TypeVisitor typeVisitor : visitors) {
  540. typeVisitor.init(oracle);
  541. }
  542. return visitors;
  543. }
  544. protected LoadStyle getLoadStyle(JClassType connectorType) {
  545. Connect annotation = connectorType.getAnnotation(Connect.class);
  546. return annotation.loadStyle();
  547. }
  548. public static String getBoxedTypeName(JType type) {
  549. if (type.isPrimitive() != null) {
  550. // Used boxed types for primitives
  551. return type.isPrimitive().getQualifiedBoxedSourceName();
  552. } else {
  553. return type.getErasedType().getQualifiedSourceName();
  554. }
  555. }
  556. public static void writeTypeCreator(SourceWriter sourceWriter, JType type) {
  557. String typeName = ConnectorBundleLoaderFactory.getBoxedTypeName(type);
  558. JParameterizedType parameterized = type.isParameterized();
  559. if (parameterized != null) {
  560. sourceWriter.print("new Type(\"" + typeName + "\", ");
  561. sourceWriter.print("new Type[] {");
  562. JClassType[] typeArgs = parameterized.getTypeArgs();
  563. for (JClassType jClassType : typeArgs) {
  564. writeTypeCreator(sourceWriter, jClassType);
  565. sourceWriter.print(", ");
  566. }
  567. sourceWriter.print("}");
  568. } else {
  569. sourceWriter.print("new Type(" + typeName + ".class");
  570. }
  571. sourceWriter.print(")");
  572. }
  573. }