use of org.apache.tapestry5.plastic.MethodInvocation in project flowlogix by flowlogix.
the class AjaxAnnotationWorker method transform.
@Override
public void transform(PlasticClass plasticClass, TransformationSupport support, MutableComponentModel model) {
boolean hasTrackerMixin = model.getMixinClassNames().contains(SessionTracker.class.getName());
for (PlasticMethod method : plasticClass.getMethodsWithAnnotation(AJAX.class)) {
final AJAX annotation = method.getAnnotation(AJAX.class);
final boolean isVoid = method.isVoid();
if (annotation.requireSession() && (!hasTrackerMixin)) {
model.addMixinClassName(SessionTracker.class.getName());
hasTrackerMixin = true;
}
method.addAdvice(new MethodAdvice() {
@Override
@SneakyThrows(IOException.class)
public void advise(MethodInvocation invocation) {
if (!request.isXHR() || annotation.requireSession() == false) {
invocation.proceed();
} else {
// do not invoke on bad sessions
if (SessionTrackerUtil.isValidSession(rg.getActivePageName(), rg.getRequest().getSession(false))) {
invocation.proceed();
} else {
showSessionExpiredMessage = true;
SessionTrackerUtil.redirectToSelf(rg, linkSource);
if (!isVoid) {
invocation.setReturnValue(null);
}
return;
}
}
Object result = null;
if (!isVoid) {
result = invocation.getReturnValue();
}
if (!request.isXHR()) {
if (result != null) {
result = defaultForReturnType(result.getClass());
}
} else {
if (annotation.discardAfter()) {
cs.getActivePage().getComponentResources().discardPersistentFieldChanges();
}
}
if (!isVoid) {
invocation.setReturnValue(result);
}
}
});
}
}
use of org.apache.tapestry5.plastic.MethodInvocation in project tapestry-5 by apache.
the class MethodAdviceManager method createNewMethod.
private void createNewMethod() {
String[] exceptions = advisedMethodNode.exceptions == null ? null : advisedMethodNode.exceptions.toArray(new String[0]);
// Remove the private flag, so that the MethodInvocation implementation (in the same package)
// can directly access the method without an additional access method.
MethodNode mn = new MethodNode(advisedMethodNode.access & ~Opcodes.ACC_PRIVATE, newMethodName, advisedMethodNode.desc, advisedMethodNode.signature, exceptions);
// Copy everything else about the advisedMethodNode over to the new node
advisedMethodNode.accept(mn);
// Add this new method, with the same implementation as the original method, to the
// PlasticClass
plasticClass.classNode.methods.add(mn);
}
use of org.apache.tapestry5.plastic.MethodInvocation in project tapestry-5 by apache.
the class CachedWorker method createFactory.
private MethodResultCacheFactory createFactory(PlasticClass plasticClass, final String watch, PlasticMethod method) {
// will suffice.
if (watch.equals("")) {
return nonWatchFactory;
}
// Because of the watch, its necessary to create a factory for instances of this component and method.
final FieldHandle bindingFieldHandle = plasticClass.introduceField(Binding.class, "cache$watchBinding$" + method.getDescription().methodName).getHandle();
// Each component instance will get its own Binding instance. That handles both different locales,
// and reuse of a component (with a cached method) within a page or across pages. However, the binding can't be initialized
// until the page loads.
plasticClass.introduceInterface(PageLifecycleListener.class);
plasticClass.introduceMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_DESCRIPTION).addAdvice(new MethodAdvice() {
public void advise(MethodInvocation invocation) {
ComponentResources resources = invocation.getInstanceContext().get(ComponentResources.class);
Binding binding = bindingSource.newBinding("@Cached watch", resources, BindingConstants.PROP, watch);
bindingFieldHandle.set(invocation.getInstance(), binding);
invocation.proceed();
}
});
return new MethodResultCacheFactory() {
public MethodResultCache create(Object instance) {
Binding binding = (Binding) bindingFieldHandle.get(instance);
return new WatchedBindingMethodResultCache(binding);
}
};
}
use of org.apache.tapestry5.plastic.MethodInvocation in project tapestry-5 by apache.
the class TapestryModule method componentReplacer.
@Advise(serviceInterface = ComponentInstantiatorSource.class)
public static void componentReplacer(MethodAdviceReceiver methodAdviceReceiver, final ComponentOverride componentReplacer) throws NoSuchMethodException, SecurityException {
if (componentReplacer.hasReplacements()) {
MethodAdvice advice = new MethodAdvice() {
@Override
public void advise(MethodInvocation invocation) {
String className = (String) invocation.getParameter(0);
final Class<?> replacement = componentReplacer.getReplacement(className);
if (replacement != null) {
invocation.setParameter(0, replacement.getName());
}
invocation.proceed();
}
};
methodAdviceReceiver.adviseMethod(ComponentInstantiatorSource.class.getMethod("getInstantiator", String.class), advice);
}
}
use of org.apache.tapestry5.plastic.MethodInvocation in project tapestry-5 by apache.
the class LazyAdvisorImpl method addAdvice.
private void addAdvice(Method method, MethodAdviceReceiver receiver) {
final Class thunkType = method.getReturnType();
final String description = String.format("<%s Thunk for %s>", thunkType.getName(), InternalUtils.asString(method));
MethodAdvice advice = new MethodAdvice() {
/**
* When the method is invoked, we don't immediately proceed. Instead, we return a thunk instance
* that defers its behavior to the lazily invoked invocation.
*/
@Override
public void advise(final MethodInvocation invocation) {
ObjectCreator deferred = new ObjectCreator() {
@Override
public Object createObject() {
invocation.proceed();
return invocation.getReturnValue();
}
};
ObjectCreator cachingObjectCreator = new CachingObjectCreator(deferred);
Object thunk = thunkCreator.createThunk(thunkType, cachingObjectCreator, description);
invocation.setReturnValue(thunk);
}
};
receiver.adviseMethod(method, advice);
}
Aggregations