2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.dialog.basic;
19  
20  import java.io.Serializable;
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import javax.faces.context.FacesContext;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.shale.dialog.Constants;
29  import org.apache.shale.dialog.DialogContext;
30  import org.apache.shale.dialog.DialogContextManager;
31  import org.apache.shale.dialog.base.AbstractDialogContextManager;
32  import org.apache.shale.dialog.basic.model.Dialog;
33  
34  /***
35   * <p>Implementation of {@link DialogContextManager} for integrating
36   * basic dialog support into the Shale Dialog Manager.</p>
37   *
38   * @since 1.0.4
39   */
40  public final class BasicDialogManager extends AbstractDialogContextManager
41    implements Serializable {
42  
43  
44      // ------------------------------------------------- DialogContext Variables
45  
46  
47      /***
48       * Serial version UID.
49       */
50      private static final long serialVersionUID = 7528541012789489425L;
51  
52  
53      /***
54       * <p><code>Map</code> of {@link Dialog} configurations, keyed
55       * by dialog name.  This value is lazily instantiated, and is also
56       * transient and may need to be regenerated.</p>
57       */
58      private transient Map dialogs = null;
59  
60  
61      /***
62       * <p>The <code>Log</code> instance for this class.  This value is lazily
63       * instantiated, and is also transient and may need to be regenerated.</p>
64       */
65      private transient Log log = null;
66  
67  
68      /***
69       * <p>Map containing all currently active {@link DialogContext} instances for
70       * the current user.</p>
71       */
72      private final Map map = new HashMap();
73  
74  
75      /***
76       * <p>Serial number used to generate dialog instance identifiers.</p>
77       */
78      private int serial = 0;
79  
80  
81      // -------------------------------------------- DialogContextManager Methods
82  
83  
84      /*** {@inheritDoc} */
85      public DialogContext create(FacesContext context, String name) {
86  
87          return create(context, name, null);
88  
89      }
90  
91  
92      /*** {@inheritDoc} */
93      public DialogContext create(FacesContext context, String name, DialogContext parent) {
94  
95          // Look up the specified dialog configuration
96          Map dialogs = dialogs(context);
97          Dialog dialog = (Dialog) dialogs.get(name);
98          if (dialog == null) {
99              throw new IllegalArgumentException("No definition for dialog name '"
100                                                + name + "' can be found");
101         }
102 
103         // Validate the specified parent (if any)
104         String parentDialogId = null;
105         if (parent != null) {
106             parentDialogId = parent.getId();
107             if (parent != get(parentDialogId)) {
108                 throw new IllegalStateException("The specified parent DialogContext '"
109                         + parentDialogId + "' is not managed by this DialogContextManager");
110             }
111         }
112 
113         // Configure a new BasicDialogContext instance
114         BasicDialogContext instance = new BasicDialogContext(this, dialog, generateId(),
115                                                               parentDialogId);
116         synchronized (map) {
117             map.put(instance.getId(), instance);
118         }
119         context.getExternalContext().getRequestMap().put(Constants.CONTEXT_BEAN, instance);
120         fireOnCreate(instance);
121         return instance;
122 
123     }
124 
125 
126     /*** @{inheritDoc} */
127     public DialogContext get(String id) {
128         return (DialogContext) map.get(id);
129     }
130 
131 
132     /*** @{inheritDoc} */
133     public void remove(DialogContext instance) {
134         boolean found = false;
135         synchronized (map) {
136             found = map.remove(instance.getId()) == instance;
137         }
138         if (found) {
139             ((BasicDialogContext) instance).deactivate();
140             fireOnRemove(instance);
141         }
142     }
143 
144 
145     // --------------------------------------------------------- Private Methods
146 
147 
148     /***
149      * <p>Return a <code>Map</code> of the configured {@link Dialog}s, keyed
150      * by logical dialog name.</p>
151      *
152      * @param context FacesContext for the current request
153      * @return The map of available dialogs, keyed by dialog logical name
154      */
155     private Map dialogs(FacesContext context) {
156 
157         // Return the cached instance (if any)
158         if (this.dialogs != null) {
159             return this.dialogs;
160         }
161 
162         // Return the previously configured application scope instance (if any)
163         this.dialogs = (Map)
164           context.getExternalContext().getApplicationMap().get(Globals.DIALOGS);
165         return this.dialogs;
166 
167     }
168 
169 
170     /***
171      * <p>Generate and return a new dialog identifier.  FIXME - switch to
172      * something that creates randomized identifiers?</p>
173      *
174      * @return The new dialog identifier
175      */
176     private String generateId() {
177         return "" + ++serial;
178     }
179 
180 
181     /***
182      * <p>Return the <code>Log</code> instance for this instance.</p>
183      *
184      * @return The {@link Log} instance used by this manager
185      */
186     private Log log() {
187         if (this.log == null) {
188             this.log = LogFactory.getLog(BasicDialogManager.class);
189         }
190         return this.log;
191     }
192 
193 
194 }