private MetaMethod validateExceptionHandlingMethod(final Decorable decorable) { // Ensure that method has exactly one parameter of type Throwable final MetaMethod method = decorable.getAsMethod(); final MetaParameter[] parms = method.getParameters(); if (!(parms.length == 1 && parms[0].getType().equals(MetaClassFactory.get(Throwable.class)))) { throw new GenerationException("Methods annotated with " + UncaughtExceptionHandler.class.getName() + " must have exactly one parameter of type " + Throwable.class.getName() + ". Invalid parameters in method: " + GenUtil.getMethodString(method) + " of type " + method.getDeclaringClass() + "."); } return method; }
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { controller.ensureMemberExposed(decorable.get()); Statement instance = decorable.getAccessStatement(); final String name = getTemplateDataFieldName((DataField) decorable.getAnnotation(), decorable.getName()); final boolean isWidget = decorable.getType().isAssignableTo(Widget.class); if (!isWidget && decorable.getType().isAnnotationPresent(Templated.class)) { instance = Stmt.invokeStatic(TemplateWidgetMapper.class, "get", instance); } else if (decorable.getType().isAssignableTo(Element.class)) { instance = Stmt.invokeStatic(ElementWrapperWidget.class, "getWidget", instance); } else if (decorable.getType().isAssignableTo(IsElement.class)) { instance = Stmt.invokeStatic(ElementWrapperWidget.class, "getWidget", Stmt.nestedCall(instance).invoke("getElement")); } else if (decorable.getType().isAssignableTo(org.jboss.errai.common.client.api.elemental2.IsElement.class)) { instance = Stmt.invokeStatic(ElementWrapperWidget.class, "getWidget", Stmt.nestedCall(instance).invoke("getElement"), null); } else if (RebindUtil.isNativeJsType(decorable.getType()) || RebindUtil.isElementalIface(decorable.getType())) { if (decorable.getType().isAssignableTo(HasValue.class)) { final MetaClass valueType = decorable.getType().getMethod("getValue", new Class[0]).getReturnType(); instance = Stmt.invokeStatic(ElementWrapperWidget.class, "getWidget", Stmt.invokeStatic(TemplateUtil.class, "asElement", instance), loadLiteral(valueType)); } else if (decorable.getType().isAssignableTo( IsWidget.class )) { instance = Stmt.nestedCall( instance ).invoke( "asWidget" ); } else { if ( !isWidget ) { throw new GenerationException( "Unable to use [" + name + "] in class [" + decorable.getDecorableDeclaringType() + "] as a @DataField. The field must be a Widget, IsWidget, or a DOM element as either a JavaScriptObject, native @JsType, or IsElement." ); saveDataField(decorable, decorable.getType(), name, decorable.getName(), instance);
private boolean enclosingTypeIsDependentScoped(final Decorable decorable) { return decorable.isEnclosingTypeDependent(); }
private void saveDataField(final Decorable decorable, final MetaClass type, final String name, final String fieldName, final Statement instance) { dataFieldMap(decorable.getInjectionContext(), decorable.getDecorableDeclaringType()).put(name, instance); dataFieldTypeMap(decorable.getInjectionContext(), decorable.getDecorableDeclaringType()).put(name, type); dataFieldAnnotationMap(decorable.getInjectionContext(), decorable.getDecorableDeclaringType()).put(name, (DataField) decorable.getAnnotation()); }
/** * Generates a {@link DestructionCallback} for the {@link Templated} component. * * @return statement representing the template destruction logic. */ private List<Statement> generateTemplateDestruction(final Decorable decorable) { final List<Statement> destructionStatements = new ArrayList<>(); final Map<String, Statement> dataFields = DataFieldCodeDecorator.aggregateDataFieldMap(decorable, decorable.getDecorableDeclaringType()); final Map<String, MetaClass> dataFieldTypes = DataFieldCodeDecorator.aggregateDataFieldTypeMap(decorable, decorable.getDecorableDeclaringType()); for (final String fieldName : dataFields.keySet()) { final Statement field = dataFields.get(fieldName); final MetaClass fieldType = dataFieldTypes.get(fieldName); if (fieldType.isAssignableTo(Element.class)) { destructionStatements.add(Stmt.invokeStatic(ElementWrapperWidget.class, "removeWidget", field)); } } if (decorable.getDecorableDeclaringType().isAssignableTo(Composite.class)) { destructionStatements.add(Stmt.invokeStatic(TemplateUtil.class, "cleanupWidget", decorable.getAccessStatement())); } else { destructionStatements.add(Stmt.invokeStatic(TemplateUtil.class, "cleanupTemplated", decorable.getAccessStatement())); } return destructionStatements; }
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { Service serviceAnno = (Service) decorable.getAnnotation(); final String svcName = serviceAnno.value().equals("") ? decorable.getName() : serviceAnno.value(); for (final Annotation a : InjectUtil.extractQualifiers(decorable.get())) { if (Local.class.equals(a.annotationType())) { local = true; final String varName = decorable.getName() + "ServiceSub"; .invoke("subscribeLocal", svcName, decorable.getAccessStatement()); .invoke("subscribe", svcName, decorable.getAccessStatement());
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { final MetaClass targetClass = decorable.getEnclosingInjectable().getInjectedType(); final List<Statement> statements = new ArrayList<Statement>(); final boolean hasRunForType = processedTypes.contains(targetClass); final Bound bound = (Bound) decorable.getAnnotation(); final boolean propertyIsEmpty = bound.property().equals(""); String property = propertyIsEmpty ? decorable.getName() : bound.property(); if (!DataBindingValidator.isValidPropertyChain(binderLookup.getDataModelType(), property)) { if (propertyIsEmpty && binderLookup.getDataModelType().equals(getValueType(decorable.getType()))) { property = "this"; throw new GenerationException("Invalid binding of field " + decorable.getName() + " in class " + targetClass + "! Property " + property + " not resolvable from class " + binderLookup.getDataModelType() Statement component = decorable.getAccessStatement(); controller.ensureMemberExposed(decorable.get()); MetaClass componentType = decorable.getType(); if (componentType.isAssignableTo(Widget.class)) { if (!decorable.get().isAnnotationPresent(Inject.class) && decorable.decorableType().equals(DecorableType.FIELD) && componentType.isDefaultInstantiable()) { Statement widgetInit = Stmt.loadVariable("this").invoke( PrivateAccessUtil.getPrivateFieldAccessorName(decorable.getAsField()), Refs.get("instance"), ObjectBuilder.newInstanceOf(componentType)); || componentType.isAssignableTo(org.jboss.errai.common.client.api.elemental2.IsElement.class)
switch (decorable.decorableType()) { case METHOD: final MetaMethod method = decorable.getAsMethod(); final MetaParameter[] parameters = method.getParameters(); if (!method.getReturnType().isVoid() && parameters.length == 0) { valueAccessor = decorable.getAccessStatement(); valueAccessor = decorable.getAccessStatement(); break; if (decorable.getAnnotation().annotationType().getPackage().getName().startsWith("org.jboss.errai")) { return; throw new RuntimeException("problem with style binding. element target type is invalid: " + decorable.decorableType()); if (decorable.getType().isAssignableTo(Widget.class)) { initStmts.add(invokeStatic(StyleBindingsRegistry.class, "get") .invoke("addElementBinding", Refs.get("instance"), decorable.getAnnotation(), nestedCall(valueAccessor).invoke("getElement"))); else if (decorable.getType().isAnnotationPresent(Templated.class)) { initStmts.add(invokeStatic(StyleBindingsRegistry.class, "get") .invoke("addElementBinding", Refs.get("instance"), decorable.getAnnotation(), Stmt.invokeStatic(TemplateWidgetMapper.class, "get", valueAccessor).invoke("getElement"))); else if (decorable.getType().isAssignableTo(com.google.gwt.dom.client.Element.class) || RebindUtil.isNativeJsType(decorable.getType()) || RebindUtil.isElementalIface(decorable.getType())) {
final String registrationHandleVar = "handleFor" + decorable.getName(); final List<Statement> bindExecStmts = new ArrayList<Statement>(); final boolean enclosingTypeIsDependent = decorable.isEnclosingTypeDependent(); if (!enclosingTypeIsDependent) { bindExecStmts.add(declareFinalVariable("instance", decorable.getEnclosingInjectable().getInjectedType(), castTo(decorable.getEnclosingInjectable().getInjectedType(), invokeStatic(Factory.class, "maybeUnwrapProxy", controller.contextGetInstanceStmt())))); bindExecStmts.add(decorable.getAccessStatement(elementAccessor)); initStmts.add(declareFinalVariable(hanldeVarName, parameterizedAs(RefHolder.class, typeParametersOf(BindingRegistrationHandle.class)), newObject(RefHolder.class))); initStmts.add(loadVariable(hanldeVarName).invoke("set", invokeStatic(StyleBindingsRegistry.class, "get") .invoke("addStyleBinding", decorable.getAnnotation().annotationType(), bindExec)));
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { MetaMethod method = decorable.getAsMethod(); MetaParameter[] params = method.getParameters(); if (params.length != 1 || !params[0].getType().getErased().equals(MetaClassFactory.get(SyncResponses.class))) { throw new GenerationException("Methods annotated with @" + Sync.class.getName() + " need to have exactly one parameter of type: " + SyncResponses.class.getName() + ". Check method: " + GenUtil.getMethodString(method) + " in class " + method.getDeclaringClass().getFullyQualifiedName()); } Sync syncAnnotation = (Sync) decorable.getAnnotation(); controller.addInitializationStatements(createInitStatements(decorable.getDecorableDeclaringType(), "obj", syncAnnotation, decorable, controller)); final Statement syncWorker = controller.getReferenceStmt("syncWorker", ClientSyncWorker.class); final Statement destruction = Stmt.nestedCall(syncWorker).invoke("stop"); controller.addDestructionStatements(Collections.singletonList(destruction)); }
@Override public void generateDecorator(Decorable decorable, FactoryController controller) { try { final Timed timed = (Timed) decorable.getAnnotation(); = decorable.getAccessStatement(); .finish().finish()); final String timerVarName = decorable.getAsMethod().getName() + "Timer"; final Statement timerVar = controller.getReferenceStmt(timerVarName, Timer.class);
final Context ctx = decorable.getCodegenContext(); final MetaParameter parm = decorable.getAsParameter(); final MetaMethod method = (MetaMethod) parm.getDeclaringMember(); if (!isEnclosingTypeDependent) { callbackStatements .add(declareFinalVariable("instance", decorable.getDecorableDeclaringType(), castTo(decorable.getEnclosingInjectable().getInjectedType(), invokeStatic(Factory.class, "maybeUnwrapProxy", controller.contextGetInstanceStmt())))); callbackStatements.add(decorable.call(Refs.get("event")));
private BlockBuilder<AnonymousClassStructureBuilder> getJsTypeSubscriptionCallback(final Decorable decorable, final FactoryController controller) { final MetaParameter parm = decorable.getAsParameter(); final MetaClass eventType = parm.getType().asBoxed(); final String parmClassName = eventType.getFullyQualifiedName(); final MetaClass callBackType = parameterizedAs(JsTypeEventObserver.class, typeParametersOf(eventType)); final AnonymousClassStructureBuilder callBack = Stmt.newObject(callBackType).extend(); BlockBuilder<AnonymousClassStructureBuilder> callBackBlock; final List<Statement> fireEventStmts = new ArrayList<>(); if (!decorable.isEnclosingTypeDependent()) { fireEventStmts.add(Stmt.declareFinalVariable("instance", decorable.getEnclosingInjectable().getInjectedType(), Stmt.invokeStatic(Factory.class, "maybeUnwrapProxy", controller.contextGetInstanceStmt()))); } fireEventStmts.add(decorable.call(Refs.get("event"))); callBackBlock = callBack.publicOverridesMethod("onEvent", Parameter.finalOf(eventType, "event")) .appendAll(fireEventStmts) .finish() .publicOverridesMethod("toString") ._(Stmt.load("JsTypeObserver: " + parmClassName).returnValue()); return callBackBlock; } }
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { final ShadowService shadowService = (ShadowService) decorable.getAnnotation(); String serviceName = null; Statement subscribeShadowStatement = null; final Class<?> javaClass = decorable.getType().asClass(); for (final Class<?> intf : javaClass.getInterfaces()) { if (intf.isAnnotationPresent(Remote.class)) { serviceName = intf.getName() + ":RPC"; final AnonymousClassStructureBuilder builder = generateMethodDelegates(intf, decorable, controller); subscribeShadowStatement = Stmt.castTo(ClientMessageBus.class, Stmt.invokeStatic(ErraiBus.class, "get")) .invoke("subscribeShadow", serviceName, builder.finish()); } if (serviceName == null) { if (shadowService.value().equals("")) { serviceName = decorable.getName(); } else { serviceName = shadowService.value(); } subscribeShadowStatement = Stmt.castTo(ClientMessageBus.class, Stmt.invokeStatic(ErraiBus.class, "get")) .invoke("subscribeShadow", serviceName, controller.contextGetInstanceStmt()); } controller.addFactoryInitializationStatements(Collections.singletonList(subscribeShadowStatement)); } }
MetaClass dataModelType; final MetaClass enclosingType = decorable.getEnclosingInjectable().getInjectedType(); final Collection<HasAnnotations> allAnnotated = getMembersAndParamsAnnotatedWith(enclosingType, Model.class); controller.addInitializationStatements( Collections.<Statement>singletonList( controller.setReferenceStmt(MODEL_VAR_NAME, DecorableType.PARAM.getAccessStatement(mp, decorable.getFactoryMetaClass())))); dataBinderRef = controller.getInstancePropertyStmt( controller.getReferenceStmt(MODEL_VAR_NAME, dataModelType), BINDER_VAR_NAME, DecorableType.FIELD.getAccessStatement(field, decorable.getFactoryMetaClass()), BINDER_VAR_NAME, DataBinder.class); final List<MetaField> modelFields = decorable.getDecorableDeclaringType().getFieldsAnnotatedWith(Model.class); if (!modelFields.isEmpty()) { throw new GenerationException("Found one or more fields annotated with @Model but missing @Inject " final List<MetaParameter> modelParameters = decorable.getDecorableDeclaringType().getParametersAnnotatedWith(Model.class); if (!modelParameters.isEmpty()) { throw new GenerationException(
/** * Translates the template using the module's i18n message bundle (only if * i18n is enabled for the module). * @param decorable * @param initStmts * @param rootTemplateElement */ private void translateTemplate(final Decorable decorable, final List<Statement> initStmts, final Statement rootTemplateElement) { initStmts.add( Stmt.invokeStatic( TemplateUtil.class, "translateTemplate", getTemplateFileName(decorable.getDecorableDeclaringType()), rootTemplateElement )); }
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { final MetaClass declaringClass = decorable.getDecorableDeclaringType(); final Templated anno = (Templated) decorable.getAnnotation(); final Class<?> templateProvider = anno.provider(); final boolean customProvider = templateProvider != Templated.DEFAULT_PROVIDER.class;
final Statement fieldsMetaMap) { final boolean composite = decorable.getType().isAssignableTo(Composite.class); final Map<String, Statement> dataFields = DataFieldCodeDecorator.aggregateDataFieldMap(decorable, decorable.getType()); for (final Entry<String, Statement> field : dataFields.entrySet()) { initStmts.add(invokeStatic(TemplateUtil.class, "compositeComponentReplace", decorable.getDecorableDeclaringType() .getFullyQualifiedName(), getTemplateFileName(decorable.getDecorableDeclaringType()), supplierOf(Cast.to(Widget.class, field.getValue())), dataFieldElements, fieldsMetaMap, field.getKey()));
MetaClass dataModelType = null; final MetaClass enclosingType = decorable.getEnclosingInjectable().getInjectedType(); final Collection<HasAnnotations> allAnnotated = getMembersAndParamsAnnotatedWith(enclosingType, AutoBound.class); dataBinderRef = DecorableType.FIELD.getAccessStatement(field, decorable.getFactoryMetaClass()); if (!field.isPublic()) { controller.addExposedField(field); assertTypeIsDataBinder(field.getType()); dataModelType = (MetaClass) field.getType().getParameterizedType().getTypeParameters()[0]; dataBinderRef = invokeStatic(decorable.getInjectionContext().getProcessingContext().getBootstrapClass(), PrivateAccessUtil.getPrivateFieldAccessorName(field), Variable.get("instance"));
private static Statement getAccessStatementForAutoBoundDataBinder(final Decorable decorable, final FactoryController controller) { final Injectable enclosingInjectable = decorable.getEnclosingInjectable(); for (final Dependency dep : enclosingInjectable.getDependencies()) { switch (dep.getDependencyType()) { return DecorableType.PARAM.getAccessStatement(paramDep.getParameter(), decorable.getFactoryMetaClass()); } else { break; controller.exposedFieldStmt(fieldDep.getField()); return DecorableType.FIELD.getAccessStatement(fieldDep.getField(), decorable.getFactoryMetaClass());