View Javadoc

1   /*
2    * Copyright 2003,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.pluto;
17  
18  import java.util.HashMap;
19  import java.util.Stack;
20  
21  import org.apache.pluto.services.ContainerService;
22  import org.apache.pluto.services.PortletContainerEnvironment;
23  
24  /***
25   * 
26   */
27  public class PortletContainerServices
28  {
29  
30      public static ContainerService get(Class service)
31      {
32          // get current environment from thread local
33          // after prepare has been called
34          Stack currentContainerServiceStack = (Stack)currentContainerService.get();
35  
36          if (currentContainerServiceStack.isEmpty())
37          {
38              throw new IllegalStateException("The prepare method was never called");
39          }
40  
41          PortletContainerEnvironment environment = (PortletContainerEnvironment)currentContainerServiceStack.peek();
42  
43          if (environment == null)
44          {
45              throw new IllegalStateException("The prepare method was never called");
46          }
47  
48          return environment.getContainerService(service);            
49      }
50  
51      public static String getUniqueContainerName()
52      {
53          // get uniqueContainerName stack out of the thread local
54          Stack currentNameStack = (Stack)currentUniqueContainerName.get();
55  
56          if (currentNameStack.isEmpty())
57          {
58              throw new IllegalStateException("The prepare method was never called");
59          }
60  
61          return(String)currentNameStack.peek();
62      }
63  
64      synchronized public static void createReference(String uniqueContainerName, PortletContainerEnvironment environment)
65      {
66          if (containerServices.containsKey(uniqueContainerName))
67          {
68              throw new IllegalArgumentException("The given container name is not unique: "+uniqueContainerName);
69          }
70  
71          containerServices.put(uniqueContainerName,  environment);
72      }
73  
74      synchronized public static void destroyReference(String uniqueContainerName)
75      {
76          // removes environment from Map of possible environments
77          containerServices.remove(uniqueContainerName);
78      }
79  
80      /***
81       * This method needs to be called to prepare the portlet container
82       * environment. This allows to have multiple container instances.
83       */
84      synchronized public static void prepare(String uniqueContainerName)
85      {
86          // get container service stack out of the thread local
87          Stack currentContainerServiceStack = (Stack)currentContainerService.get();
88          // add current environment to stack stored in thread local
89          currentContainerServiceStack.push(containerServices.get(uniqueContainerName));
90  
91          // get uniqueContainerName stack out of the thread local
92          Stack currentNameStack = (Stack)currentUniqueContainerName.get();
93          // add current uniqueContainerName to stack stored in thread local
94          currentNameStack.push(uniqueContainerName);
95      }
96  
97      /***
98       * Releases the current container services.
99       */
100     public static void release()
101     {
102         // remove current environment from thread local
103         // after prepare has been called
104         Stack currentContainerServiceStack = (Stack)currentContainerService.get();
105         if (!currentContainerServiceStack.isEmpty())
106         {
107             currentContainerServiceStack.pop();
108         }
109 
110         // remove uniqueContainerName from thread local
111         // after prepare has been called
112         Stack currentNameStack = (Stack)currentUniqueContainerName.get();
113         if (!currentNameStack.isEmpty())
114         {
115             currentNameStack.pop();
116         }
117     }
118 
119     // holds a stack of the current environments for temporary use
120     private static ThreadLocal currentContainerService = new StackedThreadLocal(); 
121     // holds the current environment reference for temporary use
122     private static ThreadLocal currentUniqueContainerName = new StackedThreadLocal(); 
123 
124     // map of possible environments
125     private static HashMap containerServices = new HashMap();  
126 
127 
128 
129     private static class StackedThreadLocal extends ThreadLocal
130     {
131         public Object initialValue()
132         {
133             return new Stack();
134         }
135     }
136 
137 }