@Override public Collection<MetaClass> provideTypesToExpose() { final Set<MetaClass> types = new HashSet<MetaClass>(); for (final MetaClass metaClass : ClassScanner.getTypesAnnotatedWith(Remote.class)) { for (final MetaMethod method : metaClass.getDeclaredMethods()) { if (!method.getReturnType().isVoid()) { types.add(method.getReturnType().getErased()); } for (final MetaParameter parameter : method.getParameters()) { final MetaClass type = parameter.getType(); types.add(type.getErased()); final MetaParameterizedType parameterizedType = type.getParameterizedType(); if (parameterizedType != null) { for (final MetaType tp : parameterizedType.getTypeParameters()) { if (tp instanceof MetaClass) { types.add(((MetaClass) tp).getErased()); } } } } } } return types; } }
private Parameter[] getParametersForDeclaration(final MetaMethod method) { final MetaParameter[] metaParams = method.getParameters(); final Parameter[] params = new Parameter[metaParams.length]; for (int i = 0; i < params.length; i++) { params[i] = Parameter.of(metaParams[i].getType().getErased(), metaParams[i].getName()); } return params; }
public Integer getIndex() { if (index == null) { final MetaClassMember member = getDeclaringMember(); final MetaParameter[] params; if (member instanceof MetaMethod) { params = ((MetaMethod) member).getParameters(); } else if (member instanceof MetaConstructor) { params = ((MetaConstructor) member).getParameters(); } else { throw new RuntimeException("Not yet implemented!"); } for (int i = 0; i < params.length; i++) { if (params[i] == this || params[i].getName().equals(getName())) { index = i; return index; } } throw new RuntimeException("Could not find index of parameter " + getName() + " in " + getDeclaringMember().getName() + " in " + getDeclaringMember().getDeclaringClassName()); } return index; } }
public String hashString() { if (_hashString != null) return _hashString; return _hashString = MetaParameter.class.getName() + ":" + getName() + ":" + getType().getFullyQualifiedName(); }
final MetaMethod getterMethod = bindable.getBeanDescriptor().getReadMethodForProperty(property); final MetaMethod setterMethod = bindable.getBeanDescriptor().getWriteMethodForProperty(property); if (getterMethod != null && !getterMethod.isFinal() && getterMethod.isPublic() && setterMethod != null && !setterMethod.isFinal() && setterMethod.isPublic()) { BlockBuilder<CaseBlockBuilder> caseBlock = switchBlock.case_(property); caseBlock .append(target().invoke(setterMethod.getName(), Cast.to(setterMethod.getParameters()[0].getType().asBoxed(), Variable.get("value")))) .append(Stmt.break_()) .finish(); final MetaClass paramType = setterMethod.getParameters()[0].getType(); wrappedListProperty = Stmt.loadVariable(property).assignValue( Cast.to(paramType, agent().invoke("ensureBoundListIsProxied", property, Stmt.loadVariable(property)))); target().invoke(setterMethod.getName(), Cast.to(paramType, Stmt.loadVariable(property))); .append(Stmt.loadVariable(property).assignValue(Cast.to(paramType, Parameter.of(paramType, property)) Parameter.of(paramType, property)) .append(loadVariable("this").invoke("changeAndFire", property, Variable.get(property)))
if (renderedMethods.contains(methodString) || method.getName().equals("hashCode") || method.getName().equals("clone") || method.getName().equals("finalize") || (method.getName().equals("equals") && method.getParameters().length == 1 && method.getParameters()[0].getType().getFullyQualifiedName().equals(Object.class.getName()))) continue; methodParms.add(Parameter.of(parameters[i].getType().getErased(), "a" + i)); BlockBuilder<ElseBlockBuilder> ifBody = Stmt.create().if_( BooleanExpressionBuilder.create(Stmt.loadVariable(stateVar))); ifBody.appendAll(getAroundInvokeStatements(method)); ifBody.appendAll(getBeforeStatements(method)); statementVars[i] = loadVariable(parms.get(i).getName()); ifBody._(loadVariable("this").invoke(PrivateAccessUtil.getPrivateMethodName(method), privateAccessStmts)); ifBody._(loadVariable("this").invoke(PrivateAccessUtil.getPrivateMethodName(method), privateAccessStmts).returnValue()); ifBody._(loadVariable(proxyVar).invoke(method, statementVars).returnValue()); ._(Stmt.loadVariable(proxyVar).invoke("hashCode").returnValue())
private AnonymousClassStructureBuilder generateMethodDelegates(final Class<?> intf, final Decorable decorable, final FactoryController controller) { .extend().publicOverridesMethod("callback", Parameter.of(Message.class, "message")) .append(Stmt.declareVariable("commandType", String.class, Stmt.loadVariable("message").invoke("getCommandType"))) .append(Stmt.declareVariable("methodParms", List.class, Stmt.loadVariable("message").invoke("get", List.class, Stmt.loadLiteral("MethodParms")))); for (final MetaMethod method : mc.getMethods()) { if (ProxyUtil.isMethodInInterface(mc, method) && ProxyUtil.shouldProxyMethod(method)) { final MetaClass[] parameterTypes = Arrays.stream(method.getParameters()).map(p -> p.getType()).toArray(MetaClass[]::new); final Statement[] objects = new Statement[parameterTypes.length]; final BlockBuilder<ElseBlockBuilder> blockBuilder = If .cond(Stmt.loadLiteral(ProxyUtil.createCallSignature(method)).invoke("equals", Stmt.loadVariable("commandType"))); blockBuilder.append(Stmt.declareFinalVariable("instance", intf, controller.contextGetInstanceStmt())); objects[i] = Stmt.castTo(parameterType, Stmt.loadVariable("methodParms").invoke("get", i)); final boolean hasReturnType = !method.getReturnType().isVoid(); final Statement methodInvocation = Stmt.nestedCall(Stmt.loadVariable("instance")).invoke(method.getName(), (Object[]) objects); final Statement invocation = (hasReturnType) ? Stmt.declareFinalVariable("ret", method.getReturnType(), methodInvocation) : methodInvocation; final Statement maybeDestroy = (decorable.isEnclosingTypeDependent()) ? Stmt.loadVariable("context").invoke("destroyInstance", Refs.get("instance")) : EmptyStatement.INSTANCE; final Statement sendResponse = (hasReturnType) ? Stmt.invokeStatic(MessageBuilder.class, "createConversation", Stmt.loadVariable("message")) .invoke("subjectProvided").invoke("with", "MethodReply", Refs.get("ret")) .invoke("noErrorHandling").invoke("sendNowWith", Stmt.invokeStatic(ErraiBus.class, "get")) : EmptyStatement.INSTANCE;
final MetaClass eventType, final FactoryController controller) { final String[] browserEventTypes = Optional .ofNullable(method.getParameters()[0].getAnnotation(ForEvent.class)) .map(anno -> anno.value()) .filter(value -> value.length > 0) .orElseGet(() -> Optional .ofNullable(eventType.getAnnotation(BrowserEvent.class)) .map(anno -> anno.value()) .orElseThrow(() -> "The event argument of %s.%s must specify event types " + "either with @%s on the call site or @%s on the event type.", declaringClass.getName(), method.getName(), ForEvent.class.getSimpleName(), BrowserEvent.class.getSimpleName())))); elementStmt = nestedCall(fieldsMap).invoke("get", dataFieldName); elementStmt = loadVariable(dataFieldElementsVarName).invoke("get", dataFieldName); final String listenerVarName = "listenerFor" + eventType.getName() + "Calling" + capitalize(method.getName());
final MetaMethod method = (MetaMethod) parm.getDeclaringMember(); final MetaClass eventType = parm.getType().asBoxed(); final String parmClassName = eventType.getFullyQualifiedName(); final List<Annotation> annotations = InjectUtil.extractQualifiers(parm); final Annotation[] qualifiers = annotations.toArray(new Annotation[annotations.size()]); AnonymousClassStructureBuilder callBack = Stmt.newObject(callBackType).extend(); callBackBlock = callBack.initialize(); for (final String qualifierName : qualifierNames) { callBackBlock.append(Stmt.loadClassMember("qualifierSet").invoke("add", qualifierName)); callBack = callBackBlock.finish(); if (!isEnclosingTypeDependent) { callbackStatements .add(declareFinalVariable("instance", decorable.getDecorableDeclaringType(), castTo(decorable.getEnclosingInjectable().getInjectedType(), callBackBlock = callBack.publicOverridesMethod("fireEvent", Parameter.finalOf(eventType, "event")) .appendAll(callbackStatements) ._(Stmt.load("Observer: " + parmClassName + " " + Arrays.toString(qualifiers)).returnValue()); final String subscrVar = method.getName() + "Subscription"; final ContextualStatementBuilder routingSubStmt = Stmt.invokeStatic(ErraiBus.class, "get").invoke("subscribe",
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; } }
public static MappingDefinition map(final MetaClass toMap, final DefinitionsFactory definitionsFactory) { if ((toMap.isAbstract() && !toMap.isEnum()) || toMap.isInterface()) { throw new RuntimeException("cannot marshal an abstract class or interface: " + toMap.getFullyQualifiedName()); if (c.getParameters().length != 0) { for (int i = 0; i < c.getParameters().length; i++) { final Annotation[] annotations = c.getParameters()[i].getAnnotations(); if (annotations.length == 0) { hasMapsTos.add(false); final MapsTo mapsTo = (MapsTo) a; final String key = mapsTo.value(); simpleConstructorMapping.mapParmToIndex(key, i, c.getParameters()[i].getType()); for (final MetaMethod method : toMap.getDeclaredMethods()) { if (method.isStatic()) { final List<Boolean> hasMapsTos = new ArrayList<>(); for (int i = 0; i < method.getParameters().length; i++) { final Annotation[] annotations = method.getParameters()[i].getAnnotations(); if (annotations.length == 0) { hasMapsTos.add(false); final MapsTo mapsTo = (MapsTo) a; final String key = mapsTo.value(); simpleFactoryMapping.mapParmToIndex(key, i, method.getParameters()[i].getType()); definition.addMemberMapping(new WriteMapping(key, method.getParameters()[0].getType(), method.getName())); writeKeys.add(key);
private static void bindHandlingMethod(final Decorable decorable, final FactoryController controller, final MetaParameter parameter) { final Statement elementAccessor; if (MetaClassFactory.get(Element.class).isAssignableFrom(parameter.getType())) { elementAccessor = Refs.get("element"); else if (MetaClassFactory.get(Style.class).isAssignableFrom(parameter.getType())) { elementAccessor = Stmt.loadVariable("element").invoke("getStyle"); throw new RuntimeException("illegal target type for style binding method: " + parameter.getType() + "; expected Element or Style"); final boolean enclosingTypeIsDependent = decorable.isEnclosingTypeDependent(); if (!enclosingTypeIsDependent) { bindExecStmts.add(declareFinalVariable("instance", decorable.getEnclosingInjectable().getInjectedType(), castTo(decorable.getEnclosingInjectable().getInjectedType(), invokeStatic(Factory.class, "maybeUnwrapProxy", controller.contextGetInstanceStmt())))); final List<Statement> destructionStmts = new ArrayList<Statement>(); 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))); .castTo(BindingRegistrationHandle.class, controller.getReferenceStmt(registrationHandleVar, RefHolder.class).invoke("get")) .invoke("cleanup")); if (enclosingTypeIsDependent) { addCleanup(decorable, controller, destructionStmts);
BlockBuilder<?> methodToAppendTo, MetaClass pageClass, Class<? extends Annotation> annotation, Parameter... optionalParams) { List<MetaMethod> annotatedMethods = pageClass.getMethodsAnnotatedWith(annotation); if (annotatedMethods.size() > 1) { throw new UnsupportedOperationException( if (!metaMethod.getReturnType().equals(MetaClassFactory.get(void.class))) { throw new UnsupportedOperationException( createAnnotionName(annotation) + " methods must have a void return type, but " + metaMethod.getDeclaringClass().getFullyQualifiedName() + "." + metaMethod.getName() + " returns " + metaMethod.getReturnType().getFullyQualifiedName()); int realParamLength = metaMethod.getParameters().length; Object[] paramValues = new Object[realParamLength + 1]; paramValues[0] = Stmt.loadVariable("widget"); MetaParameter realParam = metaMethod.getParameters()[i - 1]; if (realParam.getType().equals(MetaClassFactory.get(param.getType().asClass()))) { paramValues[i] = Stmt.loadVariable(param.getName()); } else { throw new UnsupportedOperationException( createAnnotionName(annotation) + " method " + metaMethod.getDeclaringClass().getFullyQualifiedName() + "." + metaMethod.getName() + " has an illegal parameter of type " + realParam.getType().getFullyQualifiedName()); methodToAppendTo.append(Stmt.loadVariable("this").invoke(PrivateAccessUtil.getPrivateMethodName(metaMethod), paramValues));
Void.TYPE, "deliver" + eventType.getSimpleName(), Parameter.of(entityType, "targetEntity")); listenerClasses.addAll(globalEntityListeners); EntityListeners entityListeners = entityType.getAnnotation(EntityListeners.class); if (entityListeners != null) { for (Class<?> listenerClass : entityListeners.value()) { for (MetaMethod callback : listenerMetaClass.getMethodsAnnotatedWith(eventType)) { if (callback.getParameters().length != 1) { throw new GenerationException("JPA lifecycle listener method " + listenerMetaClass.getName() + "." + callback.getName() + " has " + callback.getParameters().length + " parameters (expected 1)"); if (!callback.getParameters()[0].getType().isAssignableFrom(entityType)) { throw new GenerationException("JPA lifecycle listener method " + listenerMetaClass.getName() + "." + callback.getName() + " parameter type " + callback.getParameters()[0].getType().getName() + " is incompatible with the entity type " + entityType.getName()); methodBuilder.append(Stmt.nestedCall(Stmt.newObject(listenerMetaClass)) .invoke(callback, Stmt.loadVariable("targetEntity"))); methodBuilder.append(Stmt.loadVariable("targetEntity").invoke(callback));
Attribute<?, ?> attr = (Attribute<?, ?>) sourceObject; String entityInstanceParam = method.getParameters()[0].getName(); String newValueParam = method.getParameters()[1].getName(); If.instanceOf(Stmt.loadVariable(entityInstanceParam), WrappedPortable.class) .append( Stmt.loadVariable(entityInstanceParam).assignValue( Stmt.castTo(WrappedPortable.class, Stmt.loadVariable(entityInstanceParam)).invoke("unwrap"))) .finish()); Stmt.loadVariable("this") .invoke(PrivateAccessUtil.getPrivateFieldAccessorName(field), Stmt.castTo(et.getJavaType(), Stmt.loadVariable(entityInstanceParam)), Stmt.castTo(MetaClassFactory.get(attr.getJavaType()).asBoxed(), Stmt.loadVariable(newValueParam)))); return Stmt.castTo(et.getJavaType(), Stmt.loadVariable(entityInstanceParam)) .invoke(setterMethodName, Stmt.castTo(MetaClassFactory.get(attr.getJavaType()).asBoxed(), Stmt.loadVariable(newValueParam)));
@Override public void makeMethodAccessible(final ClassStructureBuilder<?> classBuilder, final MetaMethod method, final Modifier[] modifiers) { final MetaMethod erasedMethod = method.getDeclaringClass().getErased().getDeclaredMethod(method.getName(), getErasedParamterTypes(method)); final List<Parameter> wrapperDefParms = new ArrayList<Parameter>(); if (!erasedMethod.isStatic()) { wrapperDefParms.add(Parameter.of(erasedMethod.getDeclaringClass().getErased(), "instance")); } final List<Parameter> methodDefParms = DefParameters.from(erasedMethod).getParameters(); wrapperDefParms.addAll(methodDefParms); Annotation[] annotations = NO_ANNOTATIONS; for (MetaParameter p : erasedMethod.getParameters()) { if (p.getType().getCanonicalName().equals("long")) { annotations = new Annotation[] { UNSAFE_NATIVE_LONG_ANNOTATION }; } } if (erasedMethod.getReturnType().getCanonicalName().equals("long")) { annotations = new Annotation[] { UNSAFE_NATIVE_LONG_ANNOTATION }; } classBuilder.publicMethod(erasedMethod.getReturnType(), PrivateAccessUtil.getPrivateMethodName(method)) .annotatedWith(annotations) .parameters(DefParameters.fromParameters(wrapperDefParms)) .modifiers(appendJsni(modifiers)) .body() ._(StringStatement.of(JSNIUtil.methodAccess(erasedMethod))) .finish(); }
private Collection<Statement> registerDeclarativeHandlers(final MetaClass bindable) { final List<MetaMethod> handlerMethods = bindable.getMethodsAnnotatedWith(org.jboss.errai.ui.shared.api.annotations.PropertyChangeHandler.class); if ( handlerMethods.isEmpty() ) return Collections.emptyList(); final List<Statement> retVal = new ArrayList<>(); for (final MetaMethod method : handlerMethods) { if (method.getParameters().length == 1 && method.getParameters()[0].getType().getFullyQualifiedName().equals(PropertyChangeEvent.class.getName())) { final String property = method.getAnnotation(org.jboss.errai.ui.shared.api.annotations.PropertyChangeHandler.class).value(); if (!property.isEmpty()) validateProperty(bindable, property); final Object handler = createHandlerForMethod(method); final ContextualStatementBuilder subStmt = (property.isEmpty() ? loadVariable("agent").invoke("addPropertyChangeHandler", handler): loadVariable("agent").invoke("addPropertyChangeHandler", property, handler)); retVal.add(subStmt); } else { throw new RuntimeException( String.format("The @ChangeHandler method [%s] must have exactly one argument of type %s.", method.getName(), PropertyChangeEvent.class.getSimpleName())); } } return retVal; }
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { if (decorable.getAsMethod().getParameters() == null || decorable.getAsMethod().getParameters().length != 1) throw new GenerationException("@ModelSetter method needs to have exactly one parameter: " + decorable.getAsMethod()); final MetaClass modelType = (MetaClass) controller.getAttribute(DataBindingUtil.BINDER_MODEL_TYPE_VALUE); if (!decorable.getAsMethod().getParameters()[0].getType().equals(modelType)) { throw new GenerationException("@ModelSetter method parameter must be of type: " + modelType); } final Statement dataBinder = controller.getReferenceStmt(DataBindingUtil.BINDER_VAR_NAME, DataBinder.class); final Statement proxyProperty = controller.addProxyProperty("dataBinder", DataBinder.class, dataBinder); final String modelParamName = decorable.getAsMethod().getParameters()[0].getName(); controller.addInvokeBefore(decorable.getAsMethod(), nestedCall(proxyProperty) .invoke("setModel", Refs.get(modelParamName), loadStatic(StateSync.class, "FROM_MODEL"))); controller.addInvokeBefore( decorable.getAsMethod(), loadVariable(modelParamName).assignValue( Cast.to(decorable.getAsMethod().getParameters()[0].getType(), nestedCall( proxyProperty).invoke("getModel")))); } }
private MetaClass assertEventType(final MetaClass declaringClass, final MetaMethod method) { final MetaClass eventType = (method.getParameters().length == 1) ? method.getParameters()[0].getType() : null; if (eventType != null) { if (eventType.isAssignableTo(Event.class) || eventType.isAssignableTo(DomEvent.class)) { return eventType; final BrowserEvent eventTypeAnno = eventType.getAnnotation(BrowserEvent.class); final boolean eventTypeMatchesAll = eventTypeAnno.value().length == 0; final Optional<ForEvent> oParamAnno = Optional.ofNullable(method.getParameters()[0].getAnnotation(ForEvent.class)).filter(anno -> anno.value().length > 0); final boolean parameterDeclaresEvent = oParamAnno.isPresent(); method.getParameters()[0].getName(), method.getName(), declaringClass.getFullyQualifiedName(), ForEvent.class.getSimpleName()); if (!eventTypeMatchesAll) { message += " and must be a subset of the following event types: " + Arrays.toString(eventTypeAnno.value());