View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.lifecycle;
20  
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.concurrent.ConcurrentHashMap;
24  
25  import javax.faces.FacesException;
26  import javax.faces.lifecycle.Lifecycle;
27  import javax.faces.lifecycle.LifecycleFactory;
28  
29  /**
30   * @author Manfred Geiler (latest modification by $Author$)
31   * @author Anton Koinov
32   * @version $Revision$ $Date$
33   */
34  public class LifecycleFactoryImpl extends LifecycleFactory
35  {
36      /**
37       * At start we used synchronized blocks for addLifecycle and getLifecycle. But thinking about it,
38       * use a ConcurrentHashMap is better, because retrieval operations (including get) generally 
39       * do not block, and it is more often retrieval (at begin of all requests) than addition (when 
40       * startup listener is called and configuration occur). 
41       */
42      private final Map<String, Lifecycle> _lifecycles = new ConcurrentHashMap<String, Lifecycle>();
43  
44      public LifecycleFactoryImpl()
45      {
46          addLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE, new LifecycleImpl());
47      }
48  
49      public void purgeLifecycle()
50      {
51          // Note this is not safe, because if by some coincidence one thread call getLifecycle between
52          // the two lines below it will throw IllegalArgumentException, but this method is not supposed 
53          // to be called in production, so it is ok.
54          _lifecycles.clear();
55          addLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE, new LifecycleImpl());
56      }
57  
58      @Override
59      public void addLifecycle(String id, Lifecycle lifecycle)
60      {
61          //synchronized (_lifecycles)
62          //{
63              if (_lifecycles.get(id) != null)
64              {
65                  throw new IllegalArgumentException("Lifecycle with id '" + id + "' already exists.");
66              }
67              _lifecycles.put(id, lifecycle);
68          //}
69      }
70  
71      @Override
72      public Lifecycle getLifecycle(String id) throws FacesException
73      {
74          //synchronized (_lifecycles)
75          //{
76              Lifecycle lifecycle = _lifecycles.get(id);
77              if (lifecycle == null)
78              {
79                  throw new IllegalArgumentException("Unknown lifecycle '" + id + "'.");
80              }
81              return lifecycle;
82          //}
83      }
84  
85      @Override
86      public Iterator<String> getLifecycleIds()
87      {
88          return _lifecycles.keySet().iterator();
89      }
90  }