View Javadoc
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.registry;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.MuleRuntimeException;
11  import org.mule.api.lifecycle.Disposable;
12  import org.mule.api.lifecycle.Initialisable;
13  import org.mule.api.lifecycle.InitialisationException;
14  import org.mule.api.lifecycle.LifecycleException;
15  import org.mule.api.lifecycle.Stoppable;
16  import org.mule.api.registry.RegistrationException;
17  import org.mule.api.registry.Registry;
18  import org.mule.config.i18n.CoreMessages;
19  import org.mule.config.i18n.MessageFactory;
20  import org.mule.lifecycle.RegistryLifecycleManager;
21  import org.mule.util.UUID;
22  
23  import java.util.Collection;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  
29  public abstract class AbstractRegistry implements Registry
30  {
31      /** the unique id for this Registry */
32      private String id;
33  
34      protected transient Log logger = LogFactory.getLog(getClass());
35  
36      protected MuleContext muleContext;
37  
38      protected RegistryLifecycleManager lifecycleManager;
39  
40      protected AbstractRegistry(String id, MuleContext muleContext)
41      {
42          if (id == null)
43          {
44              throw new MuleRuntimeException(CoreMessages.objectIsNull("RegistryID"));
45          }
46          this.id = id;
47          this.muleContext = muleContext;
48          lifecycleManager = createLifecycleManager();
49      }
50  
51      public final synchronized void dispose()
52      {
53          if(lifecycleManager.getState().isStarted())
54          {
55              try
56              {
57                  getLifecycleManager().fireLifecycle(Stoppable.PHASE_NAME);
58              }
59              catch (LifecycleException e)
60              {
61                  logger.error("Failed to shut down registry cleanly: " + getRegistryId(), e);
62              }
63          }
64          //Fire dispose lifecycle before calling doDispose() that that registries can clear any object caches once all objects
65          //are disposed
66          try
67          {
68              getLifecycleManager().fireLifecycle(Disposable.PHASE_NAME);
69          }
70          catch (LifecycleException e)
71          {
72              logger.error("Failed to shut down registry cleanly: " + getRegistryId(), e);
73          }
74  
75          try
76          {
77              doDispose();
78          }
79          catch (Exception e)
80          {
81              logger.error("Failed to cleanly dispose: " + e.getMessage(), e);
82          }
83      }
84  
85      protected RegistryLifecycleManager createLifecycleManager()
86      {
87          return new RegistryLifecycleManager(getRegistryId(), this, muleContext);
88      }
89  
90      abstract protected void doInitialise() throws InitialisationException;
91  
92      abstract protected void doDispose();
93  
94      public final void initialise() throws InitialisationException
95      {
96          if (id == null)
97          {
98              logger.warn("No unique id has been set on this registry");
99              id = UUID.getUUID();
100         }
101         try
102         {
103             doInitialise();
104         }
105         catch (InitialisationException e)
106         {
107             throw e;
108         }
109         catch (Exception e)
110         {
111             throw new InitialisationException(e, this);
112         }
113         try
114         {
115             fireLifecycle(Initialisable.PHASE_NAME);
116         }
117         catch (InitialisationException e)
118         {
119             throw e;
120         }
121         catch (LifecycleException e)
122         {
123             throw new InitialisationException(e, this);
124         }
125     }
126 
127     public RegistryLifecycleManager getLifecycleManager()
128     {
129         return lifecycleManager;
130     }
131 
132     public void fireLifecycle(String phase) throws LifecycleException
133     {
134         //Implicitly call stop if necessary when disposing
135         if(Disposable.PHASE_NAME.equals(phase) && lifecycleManager.getState().isStarted())
136         {
137             getLifecycleManager().fireLifecycle(Stoppable.PHASE_NAME);
138         }
139         getLifecycleManager().fireLifecycle(phase);
140     }
141 
142     @SuppressWarnings("unchecked")
143     public <T> T get(String key)
144     {
145         return (T) lookupObject(key);
146     }
147 
148     public <T> T lookupObject(Class<T> type) throws RegistrationException
149     {
150         // Accumulate objects from all registries.
151         Collection<T> objects = lookupObjects(type);
152         
153         if (objects.size() == 1)
154         {
155             return objects.iterator().next();
156         }
157         else if (objects.size() > 1)
158         {
159             throw new RegistrationException(MessageFactory.createStaticMessage("More than one object of type " + type + " registered but only one expected."));
160         }
161         else
162         {
163             return null;
164         }
165     }
166     
167     public <T> Collection<T> lookupObjectsForLifecycle(Class<T> type)
168     {
169         // By default use the normal lookup. If a registry implementation needs a
170         // different lookup implementation for lifecycle it should override this
171         // method
172         return lookupObjects(type);
173     }
174 
175 
176     // /////////////////////////////////////////////////////////////////////////
177     // Registry Metadata
178     // /////////////////////////////////////////////////////////////////////////
179 
180     public final String getRegistryId()
181     {
182         return id;
183     }
184 }