1    package com.instantbank.lettertemplate.control.web;
2    
3    import java.io.Serializable;
4    import javax.servlet.http.HttpServletRequest;
5    import javax.servlet.http.HttpSession;
6    import javax.servlet.ServletContext;
7    import java.util.HashMap;
8    import java.util.Iterator;
9    import java.util.Locale;
10   import com.instantbank.lettertemplate.control.util.WebKeys;
11   import com.instantbank.lettertemplate.control.web.handlers.FlowHandler;
12   import com.instantbank.common.utilcomponents.Debug;
13   import com.instantbank.lettertemplate.control.LetterTemplateEventException;
14   
15   /**
16    *  Looks at the Request URL and maps the request to the screen (page) for the
17    *  web-templating mechanism.
18    *
19    * @author Instant-bank (Consuelo Franky)
20    * @created August 2002
21    */
22   public class ScreenFlowManager
23       implements Serializable {
24   
25     // structures with definition of screens and of its transitions
26   
27     private HashMap screens;
28     private HashMap urlMappings;
29     private HashMap screenDefinitionMappings;
30     private Debug debug = null;
31   
32     private String defaultScreen = "INDEX";
33   
34   
35     /**
36      *  Constructor for the ScreenFlowManager object
37      */
38     public ScreenFlowManager() {
39       debug = new Debug();
40       debug.setDebugginOn(true);
41       debug.setPreMessage("** ScreenFlowManager: ");
42       screens = new HashMap();
43     }
44   
45   
46     /**
47      *  build structures of  definition of screens and of its transitions
48      *  from xml files
49      *
50      * @param context web context
51      */
52     public void init(ServletContext context) {
53       String screenDefinitionsURL = null;
54       String requestMappingsURL = null;
55       try {
56         requestMappingsURL
57           = context.getResource
58           ("/WEB-INF/xml/requestmappings.xml").toString();
59       }
60       catch(java.net.MalformedURLException ex) {
61         debug.println("Initializing ScreenFlowManager "
62           + " malformed URL exception: " + ex);
63       }
64       // get preferred local here and load the
65       // preferred languaqe accordingly:
66   
67       screenDefinitionMappings
68         = ScreenFlowXmlDAO.loadScreenDefinitionMappings
69         (requestMappingsURL);
70       Iterator it = screenDefinitionMappings.keySet().iterator();
71       while(it.hasNext()) {
72         String language = (String)it.next();
73         debug.println("loading screen definitions " +
74           " for language " + language);
75         try {
76           String mappings
77              = (String)screenDefinitionMappings.get(language);
78           debug.println("mappings are: "
79             + mappings);
80           screenDefinitionsURL
81             = context.getResource(mappings).toString();
82         }
83         catch(java.net.MalformedURLException ex) {
84           debug.println(" initializing "
85             + "ScreenFlowManager malformed URL exception: " + ex);
86         }
87         HashMap screenDefinitions
88            = ScreenFlowXmlDAO.loadScreenDefinitions
89           (screenDefinitionsURL);
90         screens.put(language, screenDefinitions);
91         urlMappings
92           = ScreenFlowXmlDAO.loadRequestMappings
93           (requestMappingsURL);
94       }
95   
96       debug.println("initialized Screens "
97         + " and URL mappings");
98     }
99   
100  
101    /**
102     *  Get the screens for the specified language.
103     *
104     * @param locale Description of the Parameter
105     * @return The screens value
106     */
107    public HashMap getScreens(Locale locale) {
108      String languageKey = locale.getLanguage()
109        + "_" + locale.getCountry();
110      if(screens.containsKey(languageKey)) {
111        return (HashMap)screens.get(languageKey);
112      }
113      return null;
114    }
115  
116  
117    /**
118     *  Get the template (JSP) for the specified language.
119     *
120     * @param locale Description of the Parameter
121     * @return The template value
122     */
123    public String getTemplate(Locale locale) {
124      HashMap localeScreens = getScreens(locale);
125      if(localeScreens == null) {
126        return null;
127      }
128      else {
129        return (String)localeScreens.get(ScreenFlowXmlDAO.TEMPLATE);
130      }
131    }
132  
133  
134    /**
135     *  The UrlMapping object contains information that will match a url to a
136     *  mapping object that contains information about the current screen, the
137     *  handler class that is needed to process a request, and the
138     *  flow handler class that is needed to insure that the propper screen is
139     *  displayed.
140     *
141     * @param urlPattern url associated to user request
142     * @return The URLMapping value
143     */
144    public URLMapping getURLMapping(String urlPattern) {
145      if((urlMappings != null) && urlMappings.containsKey(urlPattern)) {
146        return (URLMapping)urlMappings.get(urlPattern);
147      }
148      else {
149        return null;
150      }
151    }
152  
153  
154    /**
155     *  Using the information we have in the request along with The url map for
156     *  the current url we will insure that the propper current screen
157     *  is selected based on the settings in both the
158     *  screendefinitions.xml file and requestmappings.xml files.
159     *
160     * @param request Http request
161     * @param answer answer to event corresponding to user request
162     * @param context web context
163     * @exception LetterTemplateEventException
164     */
165    public void getNextScreen(HttpServletRequest request, Object answer,
166                              ServletContext context)
167       throws LetterTemplateEventException {
168      String selectedURL = request.getPathInfo();
169      // ej:"/index", "/error"
170      debug.println("selectedURL:" + selectedURL);
171  
172      String currentScreen = defaultScreen;
173  
174      URLMapping urlMapping = getURLMapping(selectedURL);
175      if(urlMapping != null) {
176        if(!urlMapping.useFlowHandler()) {
177          currentScreen = urlMapping.getScreen();
178        }
179        else {
180          debug.println("using flow handler for:" + selectedURL);
181          // load the flow handler:
182          FlowHandler handler = null;
183          String flowHandlerString = urlMapping.getFlowHandler();
184          try {
185            handler
186              = (FlowHandler)getClass().getClassLoader()
187              .loadClass(flowHandlerString).newInstance();
188            // cache the handler?
189            // invoke the processFlow(HttpServletRequest)
190            handler.doStart(request);
191            // code of output screen :
192            String flowResult = handler.processFlow
193              (request, answer, context);
194            debug.println("flow handler " +
195              " processing result=" + flowResult);
196            handler.doEnd(request);
197            // get the matching screen from the URLMapping object
198            currentScreen = urlMapping.getResultScreen(flowResult);
199  
200          }
201          catch(Exception ex) {
202            debug.println("caught loading handler: " + ex);
203            throw new LetterTemplateEventException(ex.getMessage());
204          }
205        }
206      }
207      // output screen is registered as web session variable :
208      request.getSession().setAttribute
209        (WebKeys.CurrentScreen, currentScreen);
210      debug.println("final currentScreen:" + currentScreen);
211    }
212  
213  
214    /**
215     *  Gets the required parameter for the current screen This method is used
216     *  by the insert tag to get the parameters needed to build a page. If a
217     *  language is not set then the default properties will be loaded.
218     *
219     * @param key name of  Parameter
220     * @param session web session
221     * @return The parameter value
222     */
223    public Parameter getParameter(String key, HttpSession session) {
224      String currentScreen
225         = (String)session.getAttribute(WebKeys.CurrentScreen);
226      Locale locale = (Locale)session.getAttribute(WebKeys.LanguageKey);
227      if(locale == null) {
228        locale = Locale.US;
229      }
230      if(currentScreen == null) {
231        currentScreen = defaultScreen;
232      }
233      if(screens == null || currentScreen == null) {
234        return null;
235      }
236      Screen screen = (Screen)getScreens(locale).get(currentScreen);
237      if(screen == null) {
238        return null;
239      }
240      return screen.getParameter(key);
241    }
242  
243  
244    /**
245     *  set default output screen (example: INDEX)
246     *
247     * @param defaultScreen The new defaultScreen value
248     */
249    public void setDefaultScreen(String defaultScreen) {
250      this.defaultScreen = defaultScreen;
251    }
252  
253  
254    /**
255     *  get the name of current screen from a web session variable
256     *
257     * @param session web session
258     * @return The currentScreen value
259     */
260    public String getCurrentScreen(HttpSession session) {
261      return (String)session.getAttribute(WebKeys.CurrentScreen);
262    }
263  }
264  
265