Search in sources :

Example 1 with PageActivationContext

use of org.apache.tapestry5.annotations.PageActivationContext in project tapestry-5 by apache.

the class LinkSourceImpl method createComponentEventLink.

public Link createComponentEventLink(Page page, String nestedId, String eventType, boolean forForm, Object... eventContext) {
    assert page != null;
    assert InternalUtils.isNonBlank(eventType);
    Page activePage = pageRenderQueue.getRenderingPage();
    // See TAPESTRY-2184
    if (activePage == null)
        activePage = page;
    String activePageName = activePage.getName();
    Object[] pageActivationContext = contextCollector.collectPageActivationContext(activePageName);
    ComponentEventRequestParameters parameters = new ComponentEventRequestParameters(activePageName, page.getName(), toBlank(nestedId), eventType, new ArrayEventContext(typeCoercer, pageActivationContext), new ArrayEventContext(typeCoercer, eventContext));
    Link link = linkEncoder.createComponentEventLink(parameters, forForm);
    for (LinkCreationListener2 listener : listeners) listener.createdComponentEventLink(link, parameters);
    return link;
}
Also used : ComponentEventRequestParameters(org.apache.tapestry5.services.ComponentEventRequestParameters) Page(org.apache.tapestry5.internal.structure.Page) LinkCreationListener2(org.apache.tapestry5.services.LinkCreationListener2) Link(org.apache.tapestry5.http.Link)

Example 2 with PageActivationContext

use of org.apache.tapestry5.annotations.PageActivationContext in project tapestry-5 by apache.

the class ComponentEventLinkEncoderImpl method createComponentEventLink.

public Link createComponentEventLink(ComponentEventRequestParameters parameters, boolean forForm) {
    StringBuilder builder = new StringBuilder(BUFFER_SIZE);
    // Build up the absolute URI.
    String activePageName = parameters.getActivePageName();
    String containingPageName = parameters.getContainingPageName();
    String eventType = parameters.getEventType();
    String nestedComponentId = parameters.getNestedComponentId();
    boolean hasComponentId = InternalUtils.isNonBlank(nestedComponentId);
    builder.append(contextPath);
    encodeAppFolderAndLocale(builder);
    builder.append(SLASH);
    builder.append(activePageName.toLowerCase());
    if (hasComponentId) {
        builder.append('.');
        builder.append(nestedComponentId);
    }
    if (!hasComponentId || !eventType.equals(EventConstants.ACTION)) {
        builder.append(':');
        builder.append(encodePageName(eventType));
    }
    appendContext(true, parameters.getEventContext(), builder);
    Link result = new LinkImpl(builder.toString(), forForm, requestSecurityManager.checkPageSecurity(activePageName), response, contextPathEncoder, baseURLSource);
    EventContext pageActivationContext = parameters.getPageActivationContext();
    if (pageActivationContext.getCount() != 0) {
        // Reuse the builder
        builder.setLength(0);
        appendContext(true, pageActivationContext, builder);
        // Omit that first slash
        result.addParameter(InternalConstants.PAGE_CONTEXT_NAME, builder.substring(1));
    }
    if (!containingPageName.equalsIgnoreCase(activePageName))
        result.addParameter(InternalConstants.CONTAINER_PAGE_NAME, encodePageName(containingPageName));
    return result;
}
Also used : Link(org.apache.tapestry5.http.Link)

Example 3 with PageActivationContext

use of org.apache.tapestry5.annotations.PageActivationContext in project tapestry-5 by apache.

the class PageActivationContextWorker method validateSortedFields.

private void validateSortedFields(List<PlasticField> sortedFields) {
    List<Integer> expectedIndexes = CollectionFactory.newList();
    List<Integer> actualIndexes = CollectionFactory.newList();
    Set<Boolean> activates = CollectionFactory.newSet();
    Set<Boolean> passivates = CollectionFactory.newSet();
    for (int i = 0; i < sortedFields.size(); ++i) {
        PlasticField field = sortedFields.get(i);
        PageActivationContext annotation = field.getAnnotation(PageActivationContext.class);
        expectedIndexes.add(i);
        actualIndexes.add(annotation.index());
        activates.add(annotation.activate());
        passivates.add(annotation.passivate());
    }
    List<String> errors = CollectionFactory.newList();
    if (!expectedIndexes.equals(actualIndexes)) {
        errors.add(String.format("Index values must start at 0 and increment by 1 (expected [%s], found [%s])", InternalUtils.join(expectedIndexes), InternalUtils.join(actualIndexes)));
    }
    if (activates.size() > 1) {
        errors.add("Illegal values for 'activate' (all fields must have the same value)");
    }
    if (passivates.size() > 1) {
        errors.add("Illegal values for 'passivate' (all fields must have the same value)");
    }
    if (!errors.isEmpty()) {
        throw new RuntimeException(String.format("Invalid values for @PageActivationContext: %s", InternalUtils.join(errors)));
    }
}
Also used : PageActivationContext(org.apache.tapestry5.annotations.PageActivationContext) PlasticField(org.apache.tapestry5.plastic.PlasticField)

Example 4 with PageActivationContext

use of org.apache.tapestry5.annotations.PageActivationContext in project tapestry-5 by apache.

the class PageActivationContextWorker method transformFields.

private void transformFields(TransformationSupport support, List<PlasticField> fields) {
    List<PlasticField> sortedFields = CollectionFactory.newList(fields);
    Collections.sort(sortedFields, INDEX_COMPARATOR);
    validateSortedFields(sortedFields);
    PlasticField firstField = sortedFields.get(0);
    PageActivationContext firstAnnotation = firstField.getAnnotation(PageActivationContext.class);
    // these arrays reduce memory usage and allow the PlasticField instances to be garbage collected
    FieldHandle[] handles = new FieldHandle[sortedFields.size()];
    String[] typeNames = new String[sortedFields.size()];
    int i = 0;
    for (PlasticField field : sortedFields) {
        handles[i] = field.getHandle();
        typeNames[i] = field.getTypeName();
        ++i;
    }
    if (firstAnnotation.activate()) {
        support.addEventHandler(EventConstants.ACTIVATE, 1, "PageActivationContextWorker activate event handler", createActivationHandler(handles, typeNames));
    }
    if (firstAnnotation.passivate()) {
        support.addEventHandler(EventConstants.PASSIVATE, 0, "PageActivationContextWorker passivate event handler", createPassivateHandler(handles));
    }
// We don't claim the field, and other workers may even replace it with a FieldConduit.
}
Also used : PageActivationContext(org.apache.tapestry5.annotations.PageActivationContext) PlasticField(org.apache.tapestry5.plastic.PlasticField) FieldHandle(org.apache.tapestry5.plastic.FieldHandle)

Example 5 with PageActivationContext

use of org.apache.tapestry5.annotations.PageActivationContext in project tapestry-5 by apache.

the class TapestryModule method provideTransformWorkers.

/**
 * Adds a number of standard component class transform workers:
 * <dl>
 * <dt>Parameter</dt>
 * <dd>Identifies parameters based on the {@link org.apache.tapestry5.annotations.Parameter} annotation</dd>
 * <dt>BindParameter</dt>
 * <dd>Support for the {@link BindParameter} annotation</dd>
 * <dt>Property</dt>
 * <dd>Generates accessor methods if {@link org.apache.tapestry5.annotations.Property} annotation is present</dd>
 * <dt>Import</dt>
 * <dd>Supports the {@link Import} annotation</dd>
 * <dt>UnclaimedField</dt>
 * <dd>Manages unclaimed fields, storing their value in a {@link PerThreadValue}</dd>
 * <dt>OnEvent</dt>
 * <dd>Handle the @OnEvent annotation, and related naming convention</dd>
 * <dt>RenderCommand</dt>
 * <dd>Ensures all components also implement {@link org.apache.tapestry5.runtime.RenderCommand}</dd>
 * <dt>SupportsInformalParameters</dt>
 * <dd>Checks for the annotation</dd>
 * <dt>RenderPhase</dt>
 * <dd>Link in render phase methods</dd>
 * <dt>Retain</dt>
 * <dd>Allows fields to retain their values between requests</dd>
 * <dt>Meta</dt>
 * <dd>Checks for meta data annotations and adds it to the component model</dd>
 * <dt>PageActivationContext</dt> <dd>Support for {@link PageActivationContext} annotation</dd>
 * <dt>DiscardAfter</dt> <dd>Support for {@link DiscardAfter} method annotation </dd>
 * <dt>MixinAfter</dt> <dd>Support for the {@link MixinAfter} mixin class annotation</dd>
 * <dt>PageReset</dt>
 * <dd>Checks for the {@link PageReset} annotation</dd>
 * <dt>Mixin</dt>
 * <dd>Adds a mixin as part of a component's implementation</dd>
 * <dt>Cached</dt>
 * <dd>Checks for the {@link org.apache.tapestry5.annotations.Cached} annotation</dd>
 * <dt>ActivationRequestParameter</dt>
 * <dd>Support for the {@link ActivationRequestParameter} annotation</dd>
 * <dt>PageLoaded, PageAttached, PageDetached</dt>
 * <dd>Support for annotations {@link PageLoaded}, {@link PageAttached}, {@link PageDetached}</dd>
 * <dt>InjectService</dt>
 * <dd>Handles the {@link org.apache.tapestry5.ioc.annotations.InjectService} annotation</dd>
 * <dt>Component</dt>
 * <dd>Defines embedded components based on the {@link org.apache.tapestry5.annotations.Component} annotation</dd>
 * <dt>Environment</dt>
 * <dd>Allows fields to contain values extracted from the {@link org.apache.tapestry5.services.Environment} service</dd>
 * <dt>ApplicationState</dt>
 * <dd>Converts fields that reference application state objects</dd>
 * <dt>Persist</dt>
 * <dd>Allows fields to store their their value persistently between requests via {@link Persist}</dd>
 * <dt>SessionAttribute</dt>
 * <dd>Support for the {@link SessionAttribute}</dd>
 * <dt>Log</dt>
 * <dd>Checks for the {@link org.apache.tapestry5.annotations.Log} annotation</dd>
 * <dt>HeartbeatDeferred
 * <dd>Support for the {@link HeartbeatDeferred} annotation, which defers method invocation to the end of the {@link Heartbeat}
 * <dt>Inject</dt>
 * <dd>Used with the {@link org.apache.tapestry5.ioc.annotations.Inject} annotation, when a value is supplied</dd>
 * <dt>Operation</dt> <dd>Support for the {@link Operation} method annotation</dd>
 * </dl>
 */
@Contribute(ComponentClassTransformWorker2.class)
@Primary
public static void provideTransformWorkers(OrderedConfiguration<ComponentClassTransformWorker2> configuration, MetaWorker metaWorker, ComponentClassResolver resolver) {
    configuration.add("Property", new PropertyWorker());
    // Order this one pretty early:
    configuration.addInstance("Operation", OperationWorker.class);
    configuration.add("RenderCommand", new RenderCommandWorker());
    configuration.addInstance("OnEvent", OnEventWorker.class);
    configuration.add("MixinAfter", new MixinAfterWorker());
    // These must come after Property, since they actually delete fields
    // that may still have the annotation
    configuration.addInstance("ApplicationState", ApplicationStateWorker.class);
    configuration.addInstance("Environment", EnvironmentalWorker.class);
    configuration.add("Component", new ComponentWorker(resolver));
    configuration.add("Mixin", new MixinWorker(resolver));
    configuration.addInstance("InjectPage", InjectPageWorker.class);
    configuration.addInstance("InjectComponent", InjectComponentWorker.class);
    configuration.addInstance("InjectContainer", InjectContainerWorker.class);
    // Default values for parameters are often some form of injection, so
    // make sure that Parameter fields are processed after injections.
    configuration.addInstance("Parameter", ParameterWorker.class);
    // bind parameter should always go after parameter to make sure all
    // parameters have been properly setup.
    configuration.addInstance("BindParameter", BindParameterWorker.class);
    configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
    configuration.addInstance("RenderPhase", RenderPhaseMethodWorker.class);
    // Import advises methods, usually render phase methods, so it must come after RenderPhase.
    configuration.addInstance("Import", ImportWorker.class);
    configuration.add("Meta", metaWorker.getWorker());
    configuration.add("Retain", new RetainWorker());
    configuration.add("PageActivationContext", new PageActivationContextWorker());
    configuration.addInstance("ActivationRequestParameter", ActivationRequestParameterWorker.class);
    configuration.addInstance("Cached", CachedWorker.class);
    configuration.addInstance("DiscardAfter", DiscardAfterWorker.class);
    add(configuration, PageLoaded.class, TransformConstants.CONTAINING_PAGE_DID_LOAD_DESCRIPTION);
    add(configuration, PageAttached.class, TransformConstants.CONTAINING_PAGE_DID_ATTACH_DESCRIPTION);
    add(configuration, PageDetached.class, TransformConstants.CONTAINING_PAGE_DID_DETACH_DESCRIPTION);
    configuration.addInstance("PageReset", PageResetAnnotationWorker.class);
    configuration.addInstance("InjectService", InjectServiceWorker.class);
    configuration.addInstance("Inject", InjectWorker.class);
    configuration.addInstance("Persist", PersistWorker.class);
    configuration.addInstance("SessionAttribute", SessionAttributeWorker.class);
    configuration.addInstance("Log", LogWorker.class);
    configuration.addInstance("HeartbeatDeferred", HeartbeatDeferredWorker.class);
    // This one is always last. Any additional private fields that aren't
    // annotated will
    // be converted to clear out at the end of the request.
    configuration.addInstance("UnclaimedField", UnclaimedFieldWorker.class, "after:*");
}
Also used : PageActivationContextWorker(org.apache.tapestry5.internal.transform.PageActivationContextWorker) PropertyWorker(org.apache.tapestry5.internal.transform.PropertyWorker) MixinWorker(org.apache.tapestry5.internal.transform.MixinWorker) RetainWorker(org.apache.tapestry5.internal.transform.RetainWorker) ComponentWorker(org.apache.tapestry5.internal.transform.ComponentWorker) InjectComponentWorker(org.apache.tapestry5.internal.transform.InjectComponentWorker) RenderCommandWorker(org.apache.tapestry5.internal.transform.RenderCommandWorker) SupportsInformalParametersWorker(org.apache.tapestry5.internal.transform.SupportsInformalParametersWorker) MixinAfterWorker(org.apache.tapestry5.internal.transform.MixinAfterWorker) Primary(org.apache.tapestry5.ioc.annotations.Primary) Contribute(org.apache.tapestry5.ioc.annotations.Contribute)

Aggregations

Link (org.apache.tapestry5.http.Link)5 PageRenderRequestParameters (org.apache.tapestry5.services.PageRenderRequestParameters)3 EventContext (org.apache.tapestry5.EventContext)2 PageActivationContext (org.apache.tapestry5.annotations.PageActivationContext)2 Page (org.apache.tapestry5.internal.structure.Page)2 FieldHandle (org.apache.tapestry5.plastic.FieldHandle)2 PlasticField (org.apache.tapestry5.plastic.PlasticField)2 ComponentEventLinkEncoder (org.apache.tapestry5.services.ComponentEventLinkEncoder)2 ComponentEventRequestParameters (org.apache.tapestry5.services.ComponentEventRequestParameters)2 LinkCreationListener2 (org.apache.tapestry5.services.LinkCreationListener2)2 Test (org.testng.annotations.Test)2 RequestGlobals (org.apache.tapestry5.http.services.RequestGlobals)1 ComponentWorker (org.apache.tapestry5.internal.transform.ComponentWorker)1 InjectComponentWorker (org.apache.tapestry5.internal.transform.InjectComponentWorker)1 MixinAfterWorker (org.apache.tapestry5.internal.transform.MixinAfterWorker)1 MixinWorker (org.apache.tapestry5.internal.transform.MixinWorker)1 PageActivationContextWorker (org.apache.tapestry5.internal.transform.PageActivationContextWorker)1 PropertyWorker (org.apache.tapestry5.internal.transform.PropertyWorker)1 RenderCommandWorker (org.apache.tapestry5.internal.transform.RenderCommandWorker)1 RetainWorker (org.apache.tapestry5.internal.transform.RetainWorker)1