/** * Appends the method that calls the {@code @PageHiding} method of the widget. * * @param pageImplBuilder The class builder for the implementation of PageNode we are adding the * method to. * @param pageClass The "content type" (Widget subclass) of the page. This is the type the user * annotated with {@code @Page}. */ private void appendPageHidingMethod( AnonymousClassStructureBuilder pageImplBuilder, MetaClass pageClass) { BlockBuilder<?> method = pageImplBuilder .publicMethod( void.class, createMethodNameFromAnnotation(PageHiding.class), Parameter.of(pageClass, "widget"), Parameter.of(NavigationControl.class, "control")) .body(); final MetaMethod pageHidingMethod = checkMethodAndAddPrivateAccessors( pageImplBuilder, method, pageClass, PageHiding.class, NavigationControl.class, "control"); /* * If the user did not provide a control parameter, we must proceed for them after the method is invoked. */ if (pageHidingMethod == null || pageHidingMethod.getParameters().length != 1) { method.append(Stmt.loadVariable("control").invoke("proceed")); } method.finish(); }
@Override public Statement getBeanInstance(final InjectableInstance injectableInstance) { final IOCProcessingContext pCtx = injectableInstance.getInjectionContext().getProcessingContext(); pCtx.append(Stmt.declareFinalVariable(varName, proxyClass, newObject(proxyClass))); final MetaClass proxyResolverRef = parameterizedAs(ProxyResolver.class, typeParametersOf(proxiedType)); final BlockBuilder<AnonymousClassStructureBuilder> proxyResolverBody = newObject(proxyResolverRef) .extend().publicOverridesMethod("resolve", Parameter.of(proxiedType, "obj")); final Statement proxyResolver = proxyResolverBody._( ProxyMaker.closeProxy(Refs.get(varName), Refs.get("obj")) ).finish().finish(); proxyResolverBody._(Stmt.loadVariable("context").invoke("addProxyReference", Refs.get(varName), Refs.get("obj"))); pCtx.append(loadVariable("context").invoke("addUnresolvedProxy", proxyResolver, proxiedType, qualifyingMetadata.getQualifiers())); for (final Statement statement : closeStatements) { proxyResolverBody.append(statement); } setRendered(true); return loadVariable(varName); }
/** * Generates a new instance of an anonymous inner class that implements the PageNode interface. * * @param pageClass The class providing the widget content for the page. * @param pageName The name of the page (to be used in the URL history fragment). */ private ObjectBuilder generateNewInstanceOfPageImpl(MetaClass pageClass, String pageName) { AnonymousClassStructureBuilder pageImplBuilder = ObjectBuilder.newInstanceOf( MetaClassFactory.parameterizedAs( PageNode.class, MetaClassFactory.typeParametersOf(pageClass))) .extend(); pageImplBuilder .publicMethod(String.class, "name") .append(Stmt.loadLiteral(pageName).returnValue()) .finish() .publicMethod(Class.class, "contentType") .append(Stmt.loadLiteral(pageClass).returnValue()) .finish() .publicMethod( void.class, "produceContent", Parameter.of(CreationalCallback.class, "callback")) .append( Stmt.nestedCall(Refs.get("bm")) .invoke("lookupBean", Stmt.loadLiteral(pageClass)) .invoke("getInstance", Stmt.loadVariable("callback"))) .finish(); appendPageHidingMethod(pageImplBuilder, pageClass); appendPageHiddenMethod(pageImplBuilder, pageClass); appendPageShowingMethod(pageImplBuilder, pageClass); appendPageShownMethod(pageImplBuilder, pageClass); return pageImplBuilder.finish(); }
/** * Appends the method that calls the {@code @PageHidden} method of the widget. * * @param pageImplBuilder The class builder for the implementation of PageNode we are adding the * method to. * @param pageClass The "content type" (Widget subclass) of the page. This is the type the user * annotated with {@code @Page}. */ private void appendPageHiddenMethod( AnonymousClassStructureBuilder pageImplBuilder, MetaClass pageClass) { BlockBuilder<?> method = pageImplBuilder .publicMethod( void.class, createMethodNameFromAnnotation(PageHidden.class), Parameter.of(pageClass, "widget")) .body(); checkMethodAndAddPrivateAccessors( pageImplBuilder, method, pageClass, PageHidden.class, HistoryToken.class, "state"); if (pageClass.getAnnotation(Singleton.class) == null && pageClass.getAnnotation(ApplicationScoped.class) == null && pageClass.getAnnotation(EntryPoint.class) == null) { method.append(Stmt.loadVariable("bm").invoke("destroyBean", Stmt.loadVariable("widget"))); } method.finish(); }
private List<MetaMethod> getSpecialTypeMethods() { final List<MetaMethod> meths = new ArrayList<MetaMethod>(); final JEnumType type = getEnclosedMetaObject().isEnum(); if (type != null) { meths.add( new GWTSpecialMethod(this, DefModifiers.none(), Scope.Public, String.class, "name")); meths.add( new GWTSpecialMethod( this, DefModifiers.none(), Scope.Public, Enum.class, "valueOf", Parameter.of(String.class, "p").getMetaParameter())); meths.add( new GWTSpecialMethod(this, DefModifiers.none(), Scope.Public, Enum[].class, "values")); } return meths; }
@Override public Statement getBeanInstance(final InjectableInstance injectableInstance) { final MetaClass type; final MetaParameterizedType pType; switch (injectableInstance.getTaskType()) { case Type: return null; case PrivateField: case Field: final MetaField field = injectableInstance.getField(); type = field.getType(); pType = type.getParameterizedType(); break; case Parameter: final MetaParameter parm = injectableInstance.getParm(); type = parm.getType(); pType = type.getParameterizedType(); break; default: throw new RuntimeException("illegal task type: " + injectableInstance.getEnclosingType()); } final MetaType[] typeArgs = pType.getTypeParameters(); final MetaClass[] typeArgsClasses = new MetaClass[typeArgs.length]; for (int i = 0; i < typeArgs.length; i++) { final MetaType argType = typeArgs[i]; if (argType instanceof MetaClass) { typeArgsClasses[i] = (MetaClass) argType; } else if (argType instanceof MetaParameterizedType) { typeArgsClasses[i] = (MetaClass) ((MetaParameterizedType) argType).getRawType(); } } final Annotation[] qualifiers = injectableInstance.getQualifiers(); final BlockBuilder<?> block = injectableInstance.getInjectionContext().getProcessingContext().getBlockBuilder(); final MetaClass providerCreationalCallback = MetaClassFactory.parameterizedAs( CreationalCallback.class, MetaClassFactory.typeParametersOf(providerInjector.getInjectedType())); final String varName = InjectUtil.getVarNameFromType( providerInjector.getConcreteInjectedType(), injectableInstance); final Statement valueRef; if (providerInjector.isSingleton() && providerInjector.isRendered()) { valueRef = Stmt.loadVariable("beanInstance") .invoke("provide", typeArgsClasses, qualifiers.length != 0 ? qualifiers : null); } else { valueRef = Stmt.load(null); } block.append( Stmt.declareFinalVariable( varName, providerCreationalCallback, Stmt.newObject(providerCreationalCallback) .extend() .publicOverridesMethod( "callback", Parameter.of(providerInjector.getInjectedType(), "beanInstance")) .append( Stmt.loadVariable(InjectUtil.getVarNameFromType(type, injectableInstance)) .invoke("callback", valueRef)) .append(Stmt.loadVariable("async").invoke("finish", Refs.get("this"))) .finish() .publicOverridesMethod("toString") .append( Stmt.load(providerInjector.getInjectedType()).invoke("getName").returnValue()) .finish() .finish())); block.append(Stmt.loadVariable("async").invoke("wait", Refs.get(varName))); block.append( Stmt.loadVariable(providerInjector.getCreationalCallbackVarName()) .invoke("getInstance", Refs.get(varName), Refs.get("context"))); return null; }
private void appendPageShowMethod( AnonymousClassStructureBuilder pageImplBuilder, MetaClass pageClass, Class<? extends Annotation> annotation, boolean addPrivateAccessors) { BlockBuilder<?> method = pageImplBuilder .publicMethod( void.class, createMethodNameFromAnnotation(annotation), Parameter.of(pageClass, "widget"), Parameter.of(HistoryToken.class, "state")) .body(); int idx = 0; method.append(Stmt.declareFinalVariable("pageState", Map.class, new HashMap<String, Object>())); for (MetaField field : pageClass.getFieldsAnnotatedWith(PageState.class)) { PageState psAnno = field.getAnnotation(PageState.class); String fieldName = field.getName(); String queryParamName = psAnno.value(); if (queryParamName == null || queryParamName.trim().isEmpty()) { queryParamName = fieldName; } if (addPrivateAccessors) { PrivateAccessUtil.addPrivateAccessStubs( PrivateAccessType.Write, "jsni", pageImplBuilder, field, new Modifier[] {}); } String injectorName = PrivateAccessUtil.getPrivateFieldInjectorName(field); MetaClass erasedFieldType = field.getType().getErased(); if (erasedFieldType.isAssignableTo(Collection.class)) { MetaClass elementType = MarshallingGenUtil.getConcreteCollectionElementType(field.getType()); if (elementType == null) { throw new UnsupportedOperationException( "Found a @PageState field with a Collection type but without a concrete type parameter. " + "Collection-typed @PageState fields must specify a concrete type parameter."); } if (erasedFieldType.equals(MetaClassFactory.get(Set.class))) { method.append(Stmt.declareVariable(fieldName, Stmt.newObject(HashSet.class))); } else if (erasedFieldType.equals(MetaClassFactory.get(List.class)) || erasedFieldType.equals(MetaClassFactory.get(Collection.class))) { method.append(Stmt.declareVariable(fieldName, Stmt.newObject(ArrayList.class))); } else { throw new UnsupportedOperationException( "Found a @PageState field which is a collection of type " + erasedFieldType.getFullyQualifiedName() + ". For collection-valued fields, only the exact types java.util.Collection, java.util.Set, and " + "java.util.List are supported at this time."); } // for (String fv{idx} : state.get({fieldName})) method.append( Stmt.loadVariable("state") .invoke("getState") .invoke("get", queryParamName) .foreach("elem", Object.class) .append( Stmt.declareVariable( "fv" + idx, Stmt.castTo(String.class, Stmt.loadVariable("elem")))) .append( Stmt.loadVariable(fieldName) .invoke( "add", paramFromStringStatement(elementType, Stmt.loadVariable("fv" + idx)))) .append( Stmt.loadVariable("pageState") .invoke("put", fieldName, Stmt.loadVariable(fieldName))) .finish()); method.append( Stmt.loadVariable("this") .invoke(injectorName, Stmt.loadVariable("widget"), Stmt.loadVariable(fieldName))); } else { method.append( Stmt.declareFinalVariable( "fv" + idx, Collection.class, Stmt.loadVariable("state").invoke("getState").invoke("get", queryParamName))); method.append( If.cond( Bool.or( Bool.isNull(Stmt.loadVariable("fv" + idx)), Stmt.loadVariable("fv" + idx).invoke("isEmpty"))) .append( Stmt.loadVariable("this") .invoke( injectorName, Stmt.loadVariable("widget"), defaultValueStatement(erasedFieldType))) .finish() .else_() .append( Stmt.loadVariable("this") .invoke( injectorName, Stmt.loadVariable("widget"), paramFromStringStatement( erasedFieldType, Stmt.loadVariable("fv" + idx).invoke("iterator").invoke("next")))) .append( Stmt.loadVariable("pageState") .invoke( "put", fieldName, Stmt.loadVariable("fv" + idx).invoke("iterator").invoke("next"))) .finish()); } idx++; } if (addPrivateAccessors) { method.append( Stmt.invokeStatic( CDI.class, "fireEvent", Stmt.newObject(NavigationEvent.class) .withParameters( Stmt.newObject(PageRequest.class) .withParameters( getPageName(pageClass), Stmt.loadVariable("pageState"))))); } checkMethodAndAddPrivateAccessors( pageImplBuilder, method, pageClass, annotation, HistoryToken.class, "state"); method.finish(); }