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;
Collection<TypeVisitor> visitors = getVisitors(typeOracle);
ConnectorBundle eagerBundle = new ConnectorBundle(
- ConnectorBundleLoader.EAGER_BUNDLE_NAME, null);
+ ConnectorBundleLoader.EAGER_BUNDLE_NAME, visitors);
+ TreeLogger eagerLogger = logger.branch(Type.TRACE,
+ "Populating eager bundle");
// Eager connectors and all RPC interfaces are loaded by default
- eagerBundle.visitTypes(logger,
- connectorsByLoadStyle.get(LoadStyle.EAGER), visitors);
- eagerBundle.visitSubTypes(logger,
- typeOracle.getType(ClientRpc.class.getName()), visitors);
- eagerBundle.visitSubTypes(logger,
- typeOracle.getType(ServerRpc.class.getName()), visitors);
+ eagerBundle.processTypes(eagerLogger,
+ connectorsByLoadStyle.get(LoadStyle.EAGER));
+ eagerBundle.processSubTypes(eagerLogger,
+ typeOracle.getType(ClientRpc.class.getName()));
+ eagerBundle.processSubTypes(eagerLogger,
+ typeOracle.getType(ServerRpc.class.getName()));
bundles.add(eagerBundle);
ConnectorBundle deferredBundle = new ConnectorBundle(
ConnectorBundleLoader.DEFERRED_BUNDLE_NAME, eagerBundle);
- deferredBundle.visitTypes(logger,
- connectorsByLoadStyle.get(LoadStyle.DEFERRED), visitors);
+ TreeLogger deferredLogger = logger.branch(Type.TRACE,
+ "Populating deferred bundle");
+ deferredBundle.processTypes(deferredLogger,
+ connectorsByLoadStyle.get(LoadStyle.DEFERRED));
bundles.add(deferredBundle);
for (JClassType type : lazy) {
ConnectorBundle bundle = new ConnectorBundle(type.getName(),
deferredBundle);
- bundle.visitTypes(logger, Collections.singleton(type), visitors);
+ TreeLogger subLogger = logger.branch(Type.TRACE, "Populating "
+ + type.getName() + " bundle");
+ bundle.processType(subLogger, type);
bundles.add(bundle);
}
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.vaadin.shared.communication.ClientRpc;
+import com.vaadin.shared.communication.ServerRpc;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.ServerConnector;
public class ConnectorBundle {
private final String name;
private final Set<JClassType> visitQueue = new HashSet<JClassType>();
private final Map<JClassType, Set<JMethod>> needsReturnType = new HashMap<JClassType, Set<JMethod>>();
- private boolean visiting = false;
+ private final Collection<TypeVisitor> visitors;
- public ConnectorBundle(String name, ConnectorBundle previousBundle) {
+ private ConnectorBundle(String name, ConnectorBundle previousBundle,
+ Collection<TypeVisitor> visitors) {
this.name = name;
this.previousBundle = previousBundle;
+ this.visitors = visitors;
+ }
+
+ public ConnectorBundle(String name, ConnectorBundle previousBundle) {
+ this(name, previousBundle, previousBundle.visitors);
+ }
+
+ public ConnectorBundle(String name, Collection<TypeVisitor> visitors) {
+ this(name, null, visitors);
}
public void setNeedsGwtConstructor(JClassType type) {
if (!needsGwtConstructor(type)) {
- if (!isTypeVisited(type)) {
- visitQueue.add(type);
- }
+ ensureVisited(type);
needsGwtConstructor.add(type);
}
}
public void setIdentifier(JClassType type, String identifier) {
if (!hasIdentifier(type, identifier)) {
- if (!isTypeVisited(type)) {
- visitQueue.add(type);
- }
+ ensureVisited(type);
Set<String> set = identifiers.get(type);
if (set == null) {
set = new HashSet<String>();
return Collections.unmodifiableSet(needsGwtConstructor);
}
- public void visitTypes(TreeLogger logger, Collection<JClassType> types,
- Collection<TypeVisitor> visitors) throws UnableToCompleteException {
+ public void processTypes(TreeLogger logger, Collection<JClassType> types)
+ throws UnableToCompleteException {
for (JClassType type : types) {
- if (!isTypeVisited(type)) {
- visitQueue.add(type);
- }
+ processType(logger, type);
}
- visitQueue(logger, visitors);
+ }
+
+ public void processType(TreeLogger logger, JClassType type)
+ throws UnableToCompleteException {
+ ensureVisited(type);
+ purgeQueue(logger);
}
private boolean isTypeVisited(JClassType type) {
}
}
- private void visitQueue(TreeLogger logger, Collection<TypeVisitor> visitors)
- throws UnableToCompleteException {
+ private void ensureVisited(JClassType type) {
+ if (!isTypeVisited(type)) {
+ visitQueue.add(type);
+ }
+ }
+
+ private void purgeQueue(TreeLogger logger) throws UnableToCompleteException {
while (!visitQueue.isEmpty()) {
- JClassType type = visitQueue.iterator().next();
+ Iterator<JClassType> iterator = visitQueue.iterator();
+ JClassType type = iterator.next();
+ iterator.remove();
+
+ if (isTypeVisited(type)) {
+ continue;
+ }
for (TypeVisitor typeVisitor : visitors) {
- try {
- typeVisitor.visit(type, this);
- } catch (NotFoundException e) {
- logger.log(Type.ERROR, e.getMessage(), e);
- throw new UnableToCompleteException();
- }
+ invokeVisitor(logger, type, typeVisitor);
}
- visitQueue.remove(type);
visitedTypes.add(type);
}
}
- public void visitSubTypes(TreeLogger logger, JClassType type,
- Collection<TypeVisitor> visitors) throws UnableToCompleteException {
- visitTypes(logger, Arrays.asList(type.getSubtypes()), visitors);
+ private void invokeVisitor(TreeLogger logger, JClassType type,
+ TypeVisitor typeVisitor) throws UnableToCompleteException {
+ TreeLogger subLogger = logger.branch(Type.TRACE,
+ "Visiting " + type.getName() + " with "
+ + typeVisitor.getClass().getSimpleName());
+ if (isConnectedConnector(type)) {
+ typeVisitor.visitConnector(subLogger, type, this);
+ } else if (isClientRpc(type)) {
+ typeVisitor.visitClientRpc(subLogger, type, this);
+ } else if (isServerRpc(type)) {
+ typeVisitor.visitServerRpc(subLogger, type, this);
+ }
+ }
+
+ public void processSubTypes(TreeLogger logger, JClassType type)
+ throws UnableToCompleteException {
+ processTypes(logger, Arrays.asList(type.getSubtypes()));
}
public void setNeedsReturnType(JClassType type, JMethod method) {
if (!isNeedsReturnType(type, method)) {
- if (!isTypeVisited(type)) {
- visitQueue.add(type);
- }
+ ensureVisited(type);
Set<JMethod> set = needsReturnType.get(type);
if (set == null) {
set = new HashSet<JMethod>();
public Map<JClassType, Set<JMethod>> getMethodReturnTypes() {
return Collections.unmodifiableMap(needsReturnType);
}
+
+ private static boolean isClientRpc(JClassType type) {
+ return isType(type, ClientRpc.class);
+ }
+
+ private static boolean isServerRpc(JClassType type) {
+ return isType(type, ServerRpc.class);
+ }
+
+ public static boolean isConnectedConnector(JClassType type) {
+ return isConnected(type) && isType(type, ServerConnector.class);
+ }
+
+ private static boolean isConnected(JClassType type) {
+ return type.isAnnotationPresent(Connect.class);
+ }
+
+ public static boolean isConnectedComponentConnector(JClassType type) {
+ return isConnected(type) && isType(type, ComponentConnector.class);
+ }
+
+ private static boolean isType(JClassType type, Class<?> class1) {
+ try {
+ return type.getOracle().getType(class1.getName())
+ .isAssignableFrom(type);
+ } catch (NotFoundException e) {
+ throw new RuntimeException("Could not find " + class1.getName(), e);
+ }
+ }
+
}
\ No newline at end of file
package com.vaadin.terminal.gwt.widgetsetutils.metadata;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.vaadin.shared.ui.Connect;
public class ConnectorInitVisitor extends TypeVisitor {
@Override
- public void visit(JClassType type, ConnectorBundle bundle) {
- if (isConnectedConnector(type)) {
- Connect connectAnnotation = type.getAnnotation(Connect.class);
- bundle.setIdentifier(type, connectAnnotation.value()
- .getCanonicalName());
- bundle.setNeedsGwtConstructor(type);
- }
+ public void visitConnector(TreeLogger logger, JClassType type,
+ ConnectorBundle bundle) {
+ logger.log(Type.INFO, type.getName() + " will be in the "
+ + bundle.getName().replaceAll("^_*", "") + " bundle");
+ Connect connectAnnotation = type.getAnnotation(Connect.class);
+ bundle.setIdentifier(type, connectAnnotation.value().getCanonicalName());
+ bundle.setNeedsGwtConstructor(type);
}
}
package com.vaadin.terminal.gwt.widgetsetutils.metadata;
+import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.NotFoundException;
public class StateInitVisitor extends TypeVisitor {
@Override
- public void visit(JClassType type, ConnectorBundle bundle)
- throws NotFoundException {
- if (isConnectedConnector(type)) {
- JMethod getState = getInheritedMethod(type, "getState");
- bundle.setNeedsReturnType(type, getState);
+ public void visitConnector(TreeLogger logger, JClassType type,
+ ConnectorBundle bundle) {
+ JMethod getState = findInheritedMethod(type, "getState");
+ bundle.setNeedsReturnType(type, getState);
- JType stateType = getState.getReturnType();
- bundle.setNeedsGwtConstructor(stateType.isClass());
- }
+ JType stateType = getState.getReturnType();
+ bundle.setNeedsGwtConstructor(stateType.isClass());
}
}
package com.vaadin.terminal.gwt.widgetsetutils.metadata;
+import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.vaadin.shared.ui.Connect;
-import com.vaadin.terminal.gwt.client.ComponentConnector;
-import com.vaadin.terminal.gwt.client.ServerConnector;
public abstract class TypeVisitor {
- private JClassType serverConnector;
- private JClassType componentConnector;
-
public void init(TypeOracle oracle) throws NotFoundException {
- serverConnector = oracle.getType(ServerConnector.class.getName());
- componentConnector = oracle.getType(ComponentConnector.class.getName());
+ // Default does nothing
}
- public abstract void visit(JClassType type, ConnectorBundle bundle)
- throws NotFoundException;
+ public void visitConnector(TreeLogger logger, JClassType type,
+ ConnectorBundle bundle) {
+ // Default does nothing
+ }
- protected boolean isConnectedConnector(JClassType type) {
- return serverConnector.isAssignableFrom(type)
- && type.isAnnotationPresent(Connect.class);
+ public void visitClientRpc(TreeLogger logger, JClassType type,
+ ConnectorBundle bundle) {
+ // Default does nothing
}
- protected boolean isConnectedComponentConnector(JClassType type) {
- return componentConnector.isAssignableFrom(type)
- && type.isAnnotationPresent(Connect.class);
+ public void visitServerRpc(TreeLogger logger, JClassType type,
+ ConnectorBundle bundle) {
+ // Default does nothing
}
- protected JMethod getInheritedMethod(JClassType type, String methodName,
- JType... params) throws NotFoundException {
+ protected JMethod findInheritedMethod(JClassType type, String methodName,
+ JType... params) {
JClassType currentType = type;
while (currentType != null) {
}
}
- throw new NotFoundException(methodName + " not found in " + type);
+ return null;
}
+
}
package com.vaadin.terminal.gwt.widgetsetutils.metadata;
+import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.NotFoundException;
public class WidgetInitVisitor extends TypeVisitor {
@Override
- public void visit(JClassType type, ConnectorBundle bundle)
- throws NotFoundException {
- if (isConnectedComponentConnector(type)) {
- JMethod getWidget = getInheritedMethod(type, "getWidget");
+ public void visitConnector(TreeLogger logger, JClassType type,
+ ConnectorBundle bundle) {
+ if (ConnectorBundle.isConnectedComponentConnector(type)) {
+ JMethod getWidget = findInheritedMethod(type, "getWidget");
bundle.setNeedsReturnType(type, getWidget);
JType widgetType = getWidget.getReturnType();