Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
MuleContextDisposePhase |
|
| 0.0;0 |
1 | /* | |
2 | * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com | |
3 | * The software in this package is published under the terms of the CPAL v1.0 | |
4 | * license, a copy of which has been included with this distribution in the | |
5 | * LICENSE.txt file. | |
6 | */ | |
7 | package org.mule.lifecycle.phases; | |
8 | ||
9 | import org.mule.api.agent.Agent; | |
10 | import org.mule.api.component.Component; | |
11 | import org.mule.api.construct.FlowConstruct; | |
12 | import org.mule.api.lifecycle.Disposable; | |
13 | import org.mule.api.lifecycle.Initialisable; | |
14 | import org.mule.api.lifecycle.LifecycleException; | |
15 | import org.mule.api.lifecycle.LifecyclePhase; | |
16 | import org.mule.api.lifecycle.Stoppable; | |
17 | import org.mule.api.model.Model; | |
18 | import org.mule.api.routing.OutboundRouter; | |
19 | import org.mule.api.routing.OutboundRouterCollection; | |
20 | import org.mule.api.source.MessageSource; | |
21 | import org.mule.api.transformer.Transformer; | |
22 | import org.mule.api.transport.Connector; | |
23 | import org.mule.config.i18n.CoreMessages; | |
24 | import org.mule.context.notification.MuleContextNotification; | |
25 | import org.mule.lifecycle.LifecycleObject; | |
26 | import org.mule.lifecycle.NotificationLifecycleObject; | |
27 | import org.mule.util.annotation.AnnotationMetaData; | |
28 | import org.mule.util.annotation.AnnotationUtils; | |
29 | ||
30 | import java.lang.reflect.Method; | |
31 | import java.util.LinkedHashSet; | |
32 | import java.util.List; | |
33 | import java.util.Set; | |
34 | ||
35 | import javax.annotation.PreDestroy; | |
36 | ||
37 | /** | |
38 | * Objects are disposed of via the Registry since the Registry manages the creation/initialisation of the objects | |
39 | * it must also take care of disposing them. However, a user may want to initiate a dispose via the | |
40 | * {@link org.mule.DefaultMuleContext} so the dispose Lifecycle phase for the {@link org.mule.DefaultMuleContext} | |
41 | * needs to call dispose on the Registry. | |
42 | * | |
43 | * The MuleContextDisposePhase defines the lifecycle behaviour when the Mule context is disposed. The MuleContext is associated | |
44 | * with one or more registries that inherit the lifecycle of the MuleContext. | |
45 | * | |
46 | * This phase is responsible for disposing objects. Any object that implements {@link org.mule.api.lifecycle.Disposable} will | |
47 | * have its {@link org.mule.api.lifecycle.Disposable#dispose()} method called. Objects are initialised in the order based on type: | |
48 | * {@link org.mule.api.service.Service}, {@link org.mule.api.model.Model}, {@link org.mule.api.agent.Agent}, {@link org.mule.api.transport.Connector}, followed | |
49 | * by any other object that implements {@link org.mule.api.lifecycle.Disposable}. | |
50 | * | |
51 | * @see org.mule.api.MuleContext | |
52 | * @see org.mule.api.lifecycle.LifecycleManager | |
53 | * @see org.mule.api.lifecycle.Disposable | |
54 | * | |
55 | * @since 3.0 | |
56 | */ | |
57 | public class MuleContextDisposePhase extends DefaultLifecyclePhase | |
58 | { | |
59 | public MuleContextDisposePhase() | |
60 | { | |
61 | 0 | super(Disposable.PHASE_NAME, Disposable.class, Initialisable.PHASE_NAME); |
62 | ||
63 | 0 | Set<LifecycleObject> orderedObjects = new LinkedHashSet<LifecycleObject>(); |
64 | // Stop in the opposite order to start | |
65 | 0 | orderedObjects.add(new NotificationLifecycleObject(FlowConstruct.class)); |
66 | 0 | orderedObjects.add(new NotificationLifecycleObject(Model.class, MuleContextNotification.class)); |
67 | 0 | orderedObjects.add(new NotificationLifecycleObject(Agent.class)); |
68 | 0 | orderedObjects.add(new NotificationLifecycleObject(Connector.class)); |
69 | 0 | orderedObjects.add(new NotificationLifecycleObject(Stoppable.class)); |
70 | 0 | orderedObjects.add(new NotificationLifecycleObject(Object.class)); |
71 | ||
72 | //Can call dispose from all lifecycle Phases | |
73 | 0 | registerSupportedPhase(LifecyclePhase.ALL_PHASES); |
74 | 0 | setOrderedLifecycleObjects(orderedObjects); |
75 | /* | |
76 | Ignored objects - | |
77 | -Component is ignored because the FlowConstruct will manage the components lifecycle | |
78 | -MessageSource disposal is managed by the connector it is associated with | |
79 | -RouterCollection is ignored because the FlowConstruct will manage the lifecycle | |
80 | -Router is ignored since its lifecycle is managed by the associated router collection | |
81 | -Transformer is ignored since the Dispose lifecycle is managed by the base {@link AbstractTransformer} by receiving | |
82 | a CONTEXT_DISPOSING event and calling dispose on the transformer. This is necessary since transformers are prototype objects | |
83 | and not managed by DI containers such as Spring after the creation of the object | |
84 | */ | |
85 | 0 | setIgnoredObjectTypes(new Class[]{Component.class, MessageSource.class, OutboundRouterCollection.class, OutboundRouter.class, Transformer.class}); |
86 | 0 | } |
87 | ||
88 | @Override | |
89 | public void applyLifecycle(Object o) throws LifecycleException | |
90 | { | |
91 | 0 | if (o == null) |
92 | { | |
93 | 0 | return; |
94 | } | |
95 | 0 | if (ignoreType(o.getClass())) |
96 | { | |
97 | 0 | return; |
98 | } | |
99 | //retain default Lifecycle behaviour | |
100 | 0 | super.applyLifecycle(o); |
101 | ||
102 | 0 | List<AnnotationMetaData> annos = AnnotationUtils.getMethodAnnotations(o.getClass(), PreDestroy.class); |
103 | 0 | if (annos.size() == 0) |
104 | { | |
105 | 0 | return; |
106 | } | |
107 | //Note that the registry has a processor that validates that there is at most one {@link PostConstruct} annotation | |
108 | //per object and that the method conforms to a lifecycle method | |
109 | 0 | AnnotationMetaData anno = annos.get(0); |
110 | try | |
111 | { | |
112 | 0 | ((Method) anno.getMember()).invoke(o); |
113 | } | |
114 | 0 | catch (Exception e) |
115 | { | |
116 | 0 | throw new LifecycleException(CoreMessages.failedToInvokeLifecycle( |
117 | (anno == null ? "null" : anno.getMember().getName()), o), e, this); | |
118 | 0 | } |
119 | 0 | } |
120 | } |