@@ -1,157 +0,0 @@ | |||
/* | |||
* Copyright 2011 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.terminal.gwt.widgetsetutils; | |||
import java.io.PrintWriter; | |||
import java.util.Date; | |||
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.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.google.gwt.user.rebind.ClassSourceFileComposerFactory; | |||
import com.google.gwt.user.rebind.SourceWriter; | |||
import com.vaadin.terminal.gwt.client.ServerConnector; | |||
import com.vaadin.terminal.gwt.client.ui.ConnectorClassBasedFactory; | |||
import com.vaadin.terminal.gwt.client.ui.ConnectorClassBasedFactory.Creator; | |||
/** | |||
* GWT generator that creates a lookup method for | |||
* {@link ConnectorClassBasedFactory} instances. | |||
* | |||
* @since 7.0 | |||
*/ | |||
public abstract class AbstractConnectorClassBasedFactoryGenerator extends | |||
Generator { | |||
@Override | |||
public String generate(TreeLogger logger, GeneratorContext context, | |||
String typeName) throws UnableToCompleteException { | |||
try { | |||
// get classType and save instance variables | |||
return generateConnectorClassBasedFactory(typeName, logger, context); | |||
} catch (Exception e) { | |||
logger.log(TreeLogger.ERROR, typeName + " creation failed", e); | |||
throw new UnableToCompleteException(); | |||
} | |||
} | |||
private String generateConnectorClassBasedFactory(String typeName, | |||
TreeLogger logger, GeneratorContext context) | |||
throws NotFoundException { | |||
TypeOracle typeOracle = context.getTypeOracle(); | |||
JClassType classType = typeOracle.getType(typeName); | |||
String superName = classType.getSimpleSourceName(); | |||
String packageName = classType.getPackage().getName(); | |||
String className = superName + "Impl"; | |||
// get print writer that receives the source code | |||
PrintWriter printWriter = null; | |||
printWriter = context.tryCreate(logger, packageName, className); | |||
// print writer if null, source code has ALREADY been generated | |||
if (printWriter == null) { | |||
return packageName + "." + className; | |||
} | |||
Date date = new Date(); | |||
// init composer, set class properties, create source writer | |||
ClassSourceFileComposerFactory composer = null; | |||
composer = new ClassSourceFileComposerFactory(packageName, className); | |||
composer.addImport(GWT.class.getName()); | |||
composer.addImport(Creator.class.getCanonicalName()); | |||
composer.setSuperclass(superName); | |||
SourceWriter sourceWriter = composer.createSourceWriter(context, | |||
printWriter); | |||
sourceWriter.indent(); | |||
// public ConnectorStateFactoryImpl() { | |||
sourceWriter.println("public " + className + "() {"); | |||
sourceWriter.indent(); | |||
JClassType serverConnectorType = typeOracle.getType(getConnectorType() | |||
.getCanonicalName()); | |||
for (JClassType connector : serverConnectorType.getSubtypes()) { | |||
// addCreator(TextAreaConnector.class, new Creator<SharedState>() { | |||
if (connector.isInterface() != null || connector.isAbstract()) { | |||
continue; | |||
} | |||
JClassType targetType = getTargetType(connector); | |||
if (targetType.isAbstract()) { | |||
continue; | |||
} | |||
sourceWriter.println("addCreator(" | |||
+ connector.getQualifiedSourceName() | |||
+ ".class, new Creator<" | |||
+ targetType.getQualifiedSourceName() + ">() {"); | |||
// public SharedState create() { | |||
sourceWriter.println("public " | |||
+ targetType.getQualifiedSourceName() + " create() {"); | |||
// return GWT.create(TextAreaState.class); | |||
sourceWriter.println("return GWT.create(" | |||
+ targetType.getQualifiedSourceName() + ".class);"); | |||
// } | |||
sourceWriter.println("}"); | |||
// }); | |||
sourceWriter.println("});"); | |||
} | |||
// End of constructor | |||
sourceWriter.outdent(); | |||
sourceWriter.println("}"); | |||
// close generated class | |||
sourceWriter.outdent(); | |||
sourceWriter.println("}"); | |||
// commit generated class | |||
context.commit(logger, printWriter); | |||
logger.log(Type.INFO, | |||
"Done. (" + (new Date().getTime() - date.getTime()) / 1000 | |||
+ "seconds)"); | |||
return packageName + "." + className; | |||
} | |||
protected abstract Class<? extends ServerConnector> getConnectorType(); | |||
protected abstract JClassType getTargetType(JClassType connectorType); | |||
protected JClassType getGetterReturnType(JClassType connector, | |||
String getterName) { | |||
try { | |||
JMethod getMethod = connector.getMethod(getterName, new JType[] {}); | |||
return (JClassType) getMethod.getReturnType(); | |||
} catch (NotFoundException e) { | |||
return getGetterReturnType(connector.getSuperclass(), getterName); | |||
} | |||
} | |||
} |
@@ -22,6 +22,7 @@ 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.JMethod; | |||
import com.google.gwt.core.ext.typeinfo.NotFoundException; | |||
import com.google.gwt.core.ext.typeinfo.TypeOracle; | |||
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; | |||
@@ -36,7 +37,9 @@ 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.StateInitVisitor; | |||
import com.vaadin.terminal.gwt.widgetsetutils.metadata.TypeVisitor; | |||
import com.vaadin.terminal.gwt.widgetsetutils.metadata.WidgetInitVisitor; | |||
public class ConnectorBundleLoaderFactory extends Generator { | |||
@@ -158,6 +161,30 @@ public class ConnectorBundleLoaderFactory extends Generator { | |||
private void printBundleData(SourceWriter w, ConnectorBundle bundle) { | |||
writeIdentifiers(w, bundle); | |||
writeGwtConstructors(w, bundle); | |||
writeReturnTypes(w, bundle); | |||
} | |||
private void writeReturnTypes(SourceWriter w, ConnectorBundle bundle) { | |||
Map<JClassType, Set<JMethod>> methodReturnTypes = bundle | |||
.getMethodReturnTypes(); | |||
for (Entry<JClassType, Set<JMethod>> entry : methodReturnTypes | |||
.entrySet()) { | |||
JClassType type = entry.getKey(); | |||
Set<JMethod> methods = entry.getValue(); | |||
for (JMethod method : methods) { | |||
// setReturnType(Class<?> type, String methodName, Type | |||
// returnType) | |||
w.print("store.setReturnType("); | |||
printClassLiteral(w, type); | |||
w.print(", \""); | |||
w.print(method.getName()); | |||
w.print("\", "); | |||
GeneratedRpcMethodProviderGenerator.writeTypeCreator(w, | |||
method.getReturnType()); | |||
w.println(");"); | |||
} | |||
} | |||
} | |||
private void writeGwtConstructors(SourceWriter w, ConnectorBundle bundle) { | |||
@@ -206,7 +233,8 @@ public class ConnectorBundleLoaderFactory extends Generator { | |||
} | |||
private List<ConnectorBundle> buildBundles(TreeLogger logger, | |||
TypeOracle typeOracle) throws NotFoundException { | |||
TypeOracle typeOracle) throws NotFoundException, | |||
UnableToCompleteException { | |||
Map<LoadStyle, Collection<JClassType>> connectorsByLoadStyle = new HashMap<LoadStyle, Collection<JClassType>>(); | |||
for (LoadStyle loadStyle : LoadStyle.values()) { | |||
@@ -234,18 +262,18 @@ public class ConnectorBundleLoaderFactory extends Generator { | |||
ConnectorBundleLoader.EAGER_BUNDLE_NAME, null); | |||
// Eager connectors and all RPC interfaces are loaded by default | |||
eagerBundle.visitTypes(connectorsByLoadStyle.get(LoadStyle.EAGER), | |||
visitors); | |||
eagerBundle.visitSubTypes( | |||
eagerBundle.visitTypes(logger, | |||
connectorsByLoadStyle.get(LoadStyle.EAGER), visitors); | |||
eagerBundle.visitSubTypes(logger, | |||
typeOracle.getType(ClientRpc.class.getName()), visitors); | |||
eagerBundle.visitSubTypes( | |||
eagerBundle.visitSubTypes(logger, | |||
typeOracle.getType(ServerRpc.class.getName()), visitors); | |||
bundles.add(eagerBundle); | |||
ConnectorBundle deferredBundle = new ConnectorBundle( | |||
ConnectorBundleLoader.DEFERRED_BUNDLE_NAME, eagerBundle); | |||
deferredBundle.visitTypes( | |||
deferredBundle.visitTypes(logger, | |||
connectorsByLoadStyle.get(LoadStyle.DEFERRED), visitors); | |||
bundles.add(deferredBundle); | |||
@@ -254,7 +282,7 @@ public class ConnectorBundleLoaderFactory extends Generator { | |||
for (JClassType type : lazy) { | |||
ConnectorBundle bundle = new ConnectorBundle(type.getName(), | |||
deferredBundle); | |||
bundle.visitTypes(Collections.singleton(type), visitors); | |||
bundle.visitTypes(logger, Collections.singleton(type), visitors); | |||
bundles.add(bundle); | |||
} | |||
@@ -264,8 +292,9 @@ public class ConnectorBundleLoaderFactory extends Generator { | |||
private Collection<TypeVisitor> getVisitors(TypeOracle oracle) | |||
throws NotFoundException { | |||
List<TypeVisitor> visitors = Arrays | |||
.<TypeVisitor> asList(new ConnectorInitVisitor()); | |||
List<TypeVisitor> visitors = Arrays.<TypeVisitor> asList( | |||
new ConnectorInitVisitor(), new StateInitVisitor(), | |||
new WidgetInitVisitor()); | |||
for (TypeVisitor typeVisitor : visitors) { | |||
typeVisitor.init(oracle); | |||
} |
@@ -1,41 +0,0 @@ | |||
/* | |||
* Copyright 2011 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.terminal.gwt.widgetsetutils; | |||
import com.google.gwt.core.ext.typeinfo.JClassType; | |||
import com.vaadin.terminal.gwt.client.ServerConnector; | |||
/** | |||
* GWT generator that creates a SharedState class for a given Connector class, | |||
* based on the return type of getState() | |||
* | |||
* @since 7.0 | |||
*/ | |||
public class ConnectorStateFactoryGenerator extends | |||
AbstractConnectorClassBasedFactoryGenerator { | |||
@Override | |||
protected JClassType getTargetType(JClassType connectorType) { | |||
return getGetterReturnType(connectorType, "getState"); | |||
} | |||
@Override | |||
protected Class<? extends ServerConnector> getConnectorType() { | |||
return ServerConnector.class; | |||
} | |||
} |
@@ -1,41 +0,0 @@ | |||
/* | |||
* Copyright 2011 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.terminal.gwt.widgetsetutils; | |||
import com.google.gwt.core.ext.typeinfo.JClassType; | |||
import com.vaadin.terminal.gwt.client.ComponentConnector; | |||
import com.vaadin.terminal.gwt.client.ServerConnector; | |||
/** | |||
* GWT generator that creates a Widget class for a given Connector class, based | |||
* on the return type of getWidget() | |||
* | |||
* @since 7.0 | |||
*/ | |||
public class ConnectorWidgetFactoryGenerator extends | |||
AbstractConnectorClassBasedFactoryGenerator { | |||
@Override | |||
protected JClassType getTargetType(JClassType connectorType) { | |||
return getGetterReturnType(connectorType, "getWidget"); | |||
} | |||
@Override | |||
protected Class<? extends ServerConnector> getConnectorType() { | |||
return ComponentConnector.class; | |||
} | |||
} |
@@ -12,7 +12,12 @@ import java.util.HashSet; | |||
import java.util.Map; | |||
import java.util.Set; | |||
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.JMethod; | |||
import com.google.gwt.core.ext.typeinfo.NotFoundException; | |||
public class ConnectorBundle { | |||
private final String name; | |||
@@ -22,6 +27,9 @@ public class ConnectorBundle { | |||
private final Map<JClassType, Set<String>> identifiers = new HashMap<JClassType, Set<String>>(); | |||
private final Set<JClassType> visitedTypes = new HashSet<JClassType>(); | |||
private final Set<JClassType> visitQueue = new HashSet<JClassType>(); | |||
private final Map<JClassType, Set<JMethod>> needsReturnType = new HashMap<JClassType, Set<JMethod>>(); | |||
private boolean visiting = false; | |||
public ConnectorBundle(String name, ConnectorBundle previousBundle) { | |||
this.name = name; | |||
@@ -30,6 +38,9 @@ public class ConnectorBundle { | |||
public void setNeedsGwtConstructor(JClassType type) { | |||
if (!needsGwtConstructor(type)) { | |||
if (!isTypeVisited(type)) { | |||
visitQueue.add(type); | |||
} | |||
needsGwtConstructor.add(type); | |||
} | |||
} | |||
@@ -45,6 +56,9 @@ public class ConnectorBundle { | |||
public void setIdentifier(JClassType type, String identifier) { | |||
if (!hasIdentifier(type, identifier)) { | |||
if (!isTypeVisited(type)) { | |||
visitQueue.add(type); | |||
} | |||
Set<String> set = identifiers.get(type); | |||
if (set == null) { | |||
set = new HashSet<String>(); | |||
@@ -80,37 +94,71 @@ public class ConnectorBundle { | |||
return Collections.unmodifiableSet(needsGwtConstructor); | |||
} | |||
public void visitTypes(Collection<JClassType> types, | |||
Collection<TypeVisitor> visitors) { | |||
public void visitTypes(TreeLogger logger, Collection<JClassType> types, | |||
Collection<TypeVisitor> visitors) throws UnableToCompleteException { | |||
for (JClassType type : types) { | |||
if (!isTypeVisited(type)) { | |||
visitQueue.add(type); | |||
} | |||
} | |||
visitQueue(visitors); | |||
visitQueue(logger, visitors); | |||
} | |||
private boolean isTypeVisited(JClassType type) { | |||
if (visitedTypes.contains(type)) { | |||
return true; | |||
} else { | |||
return previousBundle != null | |||
&& previousBundle.isTypeVisited(type); | |||
return previousBundle != null && previousBundle.isTypeVisited(type); | |||
} | |||
} | |||
private void visitQueue(Collection<TypeVisitor> visitors) { | |||
private void visitQueue(TreeLogger logger, Collection<TypeVisitor> visitors) | |||
throws UnableToCompleteException { | |||
while (!visitQueue.isEmpty()) { | |||
JClassType type = visitQueue.iterator().next(); | |||
for (TypeVisitor typeVisitor : visitors) { | |||
typeVisitor.visit(type, this); | |||
try { | |||
typeVisitor.visit(type, this); | |||
} catch (NotFoundException e) { | |||
logger.log(Type.ERROR, e.getMessage(), e); | |||
throw new UnableToCompleteException(); | |||
} | |||
} | |||
visitQueue.remove(type); | |||
visitedTypes.add(type); | |||
} | |||
} | |||
public void visitSubTypes(JClassType type, Collection<TypeVisitor> visitors) { | |||
visitTypes(Arrays.asList(type.getSubtypes()), visitors); | |||
public void visitSubTypes(TreeLogger logger, JClassType type, | |||
Collection<TypeVisitor> visitors) throws UnableToCompleteException { | |||
visitTypes(logger, Arrays.asList(type.getSubtypes()), visitors); | |||
} | |||
public void setNeedsReturnType(JClassType type, JMethod method) { | |||
if (!isNeedsReturnType(type, method)) { | |||
if (!isTypeVisited(type)) { | |||
visitQueue.add(type); | |||
} | |||
Set<JMethod> set = needsReturnType.get(type); | |||
if (set == null) { | |||
set = new HashSet<JMethod>(); | |||
needsReturnType.put(type, set); | |||
} | |||
set.add(method); | |||
} | |||
} | |||
private boolean isNeedsReturnType(JClassType type, JMethod method) { | |||
if (needsReturnType.containsKey(type) | |||
&& needsReturnType.get(type).contains(method)) { | |||
return true; | |||
} else { | |||
return previousBundle != null | |||
&& previousBundle.isNeedsReturnType(type, method); | |||
} | |||
} | |||
public Map<JClassType, Set<JMethod>> getMethodReturnTypes() { | |||
return Collections.unmodifiableMap(needsReturnType); | |||
} | |||
} |
@@ -5,24 +5,14 @@ | |||
package com.vaadin.terminal.gwt.widgetsetutils.metadata; | |||
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.vaadin.shared.ui.Connect; | |||
import com.vaadin.terminal.gwt.client.ServerConnector; | |||
public class ConnectorInitVisitor implements TypeVisitor { | |||
private JClassType serverConnector; | |||
@Override | |||
public void init(TypeOracle oracle) throws NotFoundException { | |||
serverConnector = oracle.getType(ServerConnector.class.getName()); | |||
} | |||
public class ConnectorInitVisitor extends TypeVisitor { | |||
@Override | |||
public void visit(JClassType type, ConnectorBundle bundle) { | |||
Connect connectAnnotation = type.getAnnotation(Connect.class); | |||
if (connectAnnotation != null && serverConnector.isAssignableFrom(type)) { | |||
if (isConnectedConnector(type)) { | |||
Connect connectAnnotation = type.getAnnotation(Connect.class); | |||
bundle.setIdentifier(type, connectAnnotation.value() | |||
.getCanonicalName()); | |||
bundle.setNeedsGwtConstructor(type); |
@@ -0,0 +1,25 @@ | |||
/* | |||
@VaadinApache2LicenseForJavaFiles@ | |||
*/ | |||
package com.vaadin.terminal.gwt.widgetsetutils.metadata; | |||
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); | |||
JType stateType = getState.getReturnType(); | |||
bundle.setNeedsGwtConstructor(stateType.isClass()); | |||
} | |||
} | |||
} |
@@ -5,11 +5,56 @@ | |||
package com.vaadin.terminal.gwt.widgetsetutils.metadata; | |||
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 interface TypeVisitor { | |||
public void init(TypeOracle oracle) throws NotFoundException; | |||
public abstract class TypeVisitor { | |||
private JClassType serverConnector; | |||
private JClassType componentConnector; | |||
public void visit(JClassType type, ConnectorBundle bundle); | |||
public void init(TypeOracle oracle) throws NotFoundException { | |||
serverConnector = oracle.getType(ServerConnector.class.getName()); | |||
componentConnector = oracle.getType(ComponentConnector.class.getName()); | |||
} | |||
public abstract void visit(JClassType type, ConnectorBundle bundle) | |||
throws NotFoundException; | |||
protected boolean isConnectedConnector(JClassType type) { | |||
return serverConnector.isAssignableFrom(type) | |||
&& type.isAnnotationPresent(Connect.class); | |||
} | |||
protected boolean isConnectedComponentConnector(JClassType type) { | |||
return componentConnector.isAssignableFrom(type) | |||
&& type.isAnnotationPresent(Connect.class); | |||
} | |||
protected JMethod getInheritedMethod(JClassType type, String methodName, | |||
JType... params) throws NotFoundException { | |||
JClassType currentType = type; | |||
while (currentType != null) { | |||
JMethod method = currentType.findMethod(methodName, params); | |||
if (method != null) { | |||
return method; | |||
} | |||
currentType = currentType.getSuperclass(); | |||
} | |||
JClassType[] interfaces = type.getImplementedInterfaces(); | |||
for (JClassType iface : interfaces) { | |||
JMethod method = iface.findMethod(methodName, params); | |||
if (method != null) { | |||
return method; | |||
} | |||
} | |||
throw new NotFoundException(methodName + " not found in " + type); | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
/* | |||
@VaadinApache2LicenseForJavaFiles@ | |||
*/ | |||
package com.vaadin.terminal.gwt.widgetsetutils.metadata; | |||
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"); | |||
bundle.setNeedsReturnType(type, getWidget); | |||
JType widgetType = getWidget.getReturnType(); | |||
bundle.setNeedsGwtConstructor(widgetType.isClass()); | |||
} | |||
} | |||
} |
@@ -61,18 +61,6 @@ | |||
<when-type-assignable | |||
class="com.vaadin.terminal.gwt.client.communication.GeneratedRpcMethodProvider" /> | |||
</generate-with> | |||
<generate-with | |||
class="com.vaadin.terminal.gwt.widgetsetutils.ConnectorWidgetFactoryGenerator"> | |||
<when-type-assignable | |||
class="com.vaadin.terminal.gwt.client.ui.ConnectorWidgetFactory" /> | |||
</generate-with> | |||
<generate-with | |||
class="com.vaadin.terminal.gwt.widgetsetutils.ConnectorStateFactoryGenerator"> | |||
<when-type-assignable | |||
class="com.vaadin.terminal.gwt.client.ui.ConnectorStateFactory" /> | |||
</generate-with> | |||
<generate-with class="com.vaadin.terminal.gwt.widgetsetutils.ConnectorBundleLoaderFactory"> | |||
<when-type-assignable class="com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader" /> |
@@ -68,6 +68,7 @@ import com.vaadin.terminal.gwt.client.communication.RpcManager; | |||
import com.vaadin.terminal.gwt.client.communication.SerializerMap; | |||
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; | |||
import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; | |||
import com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader; | |||
import com.vaadin.terminal.gwt.client.metadata.Type; | |||
import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; | |||
import com.vaadin.terminal.gwt.client.ui.VContextMenu; | |||
@@ -240,6 +241,10 @@ public class ApplicationConnection { | |||
initializeClientHooks(); | |||
// Assuming Root data is eagerly loaded | |||
ConnectorBundleLoader.get().loadBundle( | |||
ConnectorBundleLoader.EAGER_BUNDLE_NAME, null); | |||
rootConnector.init(cnf.getRootPanelId(), this); | |||
showLoadingIndicator(); | |||
} |
@@ -67,7 +67,9 @@ public abstract class ConnectorBundleLoader { | |||
List<BundleLoadCallback> callbacks = asyncBlockLoaders.get(packageName) | |||
.setLoaded(); | |||
for (BundleLoadCallback callback : callbacks) { | |||
callback.loaded(); | |||
if (callback != null) { | |||
callback.loaded(); | |||
} | |||
} | |||
} | |||
@@ -37,6 +37,8 @@ import com.vaadin.terminal.gwt.client.UIDL; | |||
import com.vaadin.terminal.gwt.client.Util; | |||
import com.vaadin.terminal.gwt.client.VConsole; | |||
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; | |||
import com.vaadin.terminal.gwt.client.metadata.Type; | |||
import com.vaadin.terminal.gwt.client.metadata.TypeData; | |||
import com.vaadin.terminal.gwt.client.ui.datefield.PopupDateFieldConnector; | |||
import com.vaadin.terminal.gwt.client.ui.root.RootConnector; | |||
@@ -77,7 +79,10 @@ public abstract class AbstractComponentConnector extends AbstractConnector | |||
* @return | |||
*/ | |||
protected Widget createWidget() { | |||
return ConnectorWidgetFactory.createWidget(getClass()); | |||
Type type = TypeData.getType(getClass()); | |||
Type widgetType = type.getMethod("getWidget").getReturnType(); | |||
Object instance = widgetType.createInstance(); | |||
return (Widget) instance; | |||
} | |||
/** |
@@ -33,6 +33,8 @@ import com.vaadin.terminal.gwt.client.Util; | |||
import com.vaadin.terminal.gwt.client.VConsole; | |||
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; | |||
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler; | |||
import com.vaadin.terminal.gwt.client.metadata.Type; | |||
import com.vaadin.terminal.gwt.client.metadata.TypeData; | |||
/** | |||
* An abstract implementation of Connector. | |||
@@ -265,7 +267,10 @@ public abstract class AbstractConnector implements ServerConnector, | |||
* @return A new state object | |||
*/ | |||
protected SharedState createState() { | |||
return ConnectorStateFactory.createState(getClass()); | |||
Type connectorType = TypeData.getType(getClass()); | |||
Type stateType = connectorType.getMethod("getState").getReturnType(); | |||
Object stateInstance = stateType.createInstance(); | |||
return (SharedState) stateInstance; | |||
} | |||
@Override |
@@ -1,52 +0,0 @@ | |||
/* | |||
* Copyright 2011 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.terminal.gwt.client.ui; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import com.vaadin.shared.Connector; | |||
public abstract class ConnectorClassBasedFactory<T> { | |||
public interface Creator<T> { | |||
public T create(); | |||
} | |||
private Map<Class<? extends Connector>, Creator<? extends T>> creators = new HashMap<Class<? extends Connector>, Creator<? extends T>>(); | |||
protected void addCreator(Class<? extends Connector> cls, | |||
Creator<? extends T> creator) { | |||
creators.put(cls, creator); | |||
} | |||
/** | |||
* Creates a widget using GWT.create for the given connector, based on its | |||
* {@link AbstractComponentConnector#getWidget()} return type. | |||
* | |||
* @param connector | |||
* @return | |||
*/ | |||
public T create(Class<? extends Connector> connector) { | |||
Creator<? extends T> foo = creators.get(connector); | |||
if (foo == null) { | |||
throw new RuntimeException(getClass().getName() | |||
+ " could not find a creator for connector of type " | |||
+ connector.getName()); | |||
} | |||
return foo.create(); | |||
} | |||
} |
@@ -1,43 +0,0 @@ | |||
/* | |||
* Copyright 2011 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.terminal.gwt.client.ui; | |||
import com.google.gwt.core.client.GWT; | |||
import com.vaadin.shared.Connector; | |||
import com.vaadin.shared.communication.SharedState; | |||
public abstract class ConnectorStateFactory extends | |||
ConnectorClassBasedFactory<SharedState> { | |||
private static ConnectorStateFactory impl = null; | |||
/** | |||
* Creates a SharedState using GWT.create for the given connector, based on | |||
* its {@link AbstractComponentConnector#getSharedState ()} return type. | |||
* | |||
* @param connector | |||
* @return | |||
*/ | |||
public static SharedState createState(Class<? extends Connector> connector) { | |||
return getImpl().create(connector); | |||
} | |||
private static ConnectorStateFactory getImpl() { | |||
if (impl == null) { | |||
impl = GWT.create(ConnectorStateFactory.class); | |||
} | |||
return impl; | |||
} | |||
} |
@@ -1,55 +0,0 @@ | |||
/* | |||
* Copyright 2011 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.terminal.gwt.client.ui; | |||
import com.google.gwt.core.client.GWT; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.terminal.gwt.client.ui.textfield.TextFieldConnector; | |||
import com.vaadin.terminal.gwt.client.ui.textfield.VTextField; | |||
public abstract class ConnectorWidgetFactory extends | |||
ConnectorClassBasedFactory<Widget> { | |||
private static ConnectorWidgetFactory impl = null; | |||
// TODO Move to generator | |||
{ | |||
addCreator(TextFieldConnector.class, new Creator<Widget>() { | |||
@Override | |||
public Widget create() { | |||
return GWT.create(VTextField.class); | |||
} | |||
}); | |||
} | |||
/** | |||
* Creates a widget using GWT.create for the given connector, based on its | |||
* {@link AbstractComponentConnector#getWidget()} return type. | |||
* | |||
* @param connector | |||
* @return | |||
*/ | |||
public static Widget createWidget( | |||
Class<? extends AbstractComponentConnector> connector) { | |||
return getImpl().create(connector); | |||
} | |||
private static ConnectorWidgetFactory getImpl() { | |||
if (impl == null) { | |||
impl = GWT.create(ConnectorWidgetFactory.class); | |||
} | |||
return impl; | |||
} | |||
} |