001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.pageflow.internal;
020:
021: import org.apache.beehive.netui.core.urls.TemplatedURLFormatter;
022: import org.apache.beehive.netui.core.urltemplates.URLTemplatesFactory;
023: import org.apache.beehive.netui.pageflow.FacesBackingBeanFactory;
024: import org.apache.beehive.netui.pageflow.FlowControllerFactory;
025: import org.apache.beehive.netui.pageflow.PageFlowUtils;
026: import org.apache.beehive.netui.pageflow.ProcessPopulate;
027: import org.apache.beehive.netui.pageflow.RequestParameterHandler;
028: import org.apache.beehive.netui.pageflow.handler.Handlers;
029: import org.apache.beehive.netui.util.config.ConfigInitializationException;
030: import org.apache.beehive.netui.util.config.ConfigUtil;
031: import org.apache.beehive.netui.util.config.bean.PrefixHandlerConfig;
032: import org.apache.beehive.netui.util.config.bean.UrlConfig;
033: import org.apache.beehive.netui.util.internal.DiscoveryUtils;
034: import org.apache.beehive.netui.util.logging.Logger;
035: import org.apache.beehive.netui.util.xml.XmlInputStreamResolver;
036:
037: import javax.servlet.ServletContext;
038: import java.io.InputStream;
039: import java.io.Serializable;
040:
041: /**
042: * Handles initialization of the Page Flow runtime.
043: */
044: public class PageFlowInitialization {
045:
046: private static final String ALREADY_INIT_ATTR = InternalConstants.ATTR_PREFIX
047: + "contextInit";
048:
049: private static final Logger _log = Logger
050: .getInstance(PageFlowInitialization.class);
051:
052: private static class TransientFlag implements Serializable {
053: private transient boolean _flag;
054:
055: public TransientFlag() {
056: _flag = true;
057: }
058:
059: public boolean isSet() {
060: return _flag;
061: }
062: }
063:
064: public static boolean isInit(ServletContext servletContext) {
065: //
066: // If the flag is present, but was serialized, then the webapp was redeployed. At this point, we want
067: // to go through the init logic again.
068: //
069: TransientFlag flag = (TransientFlag) servletContext
070: .getAttribute(ALREADY_INIT_ATTR);
071: return flag != null && flag.isSet();
072: }
073:
074: public static void performInitializations(
075: ServletContext servletContext,
076: XmlInputStreamResolver overrideConfigInput) {
077: servletContext.setAttribute(ALREADY_INIT_ATTR,
078: new TransientFlag());
079:
080: //
081: // Initialize the config file, unless it's already initialized. This can happen because the scope for the
082: // config (static) isn't the same as the scope for PageFlowActionServlet, which may get created and destroyed
083: // within a classloader (which is the case during StrutsTestCase tests).
084: //
085: if (!ConfigUtil.isInit()) {
086: XmlInputStreamResolver resolver = overrideConfigInput != null ? overrideConfigInput
087: : new NetUIConfigResolver(servletContext);
088: try {
089: ConfigUtil.init(resolver);
090: } catch (ConfigInitializationException e) {
091: _log.fatal("Could not initialize from "
092: + resolver.getResourcePath(), e);
093: throw new IllegalStateException(
094: "Could not initialize from "
095: + resolver.getResourcePath(), e);
096: }
097: }
098:
099: AdapterManager.initServletContext(servletContext);
100: LegacySettings.init(servletContext);
101: Handlers.init(servletContext);
102: FlowControllerFactory.init(servletContext);
103: FacesBackingBeanFactory.init(servletContext);
104: initPrefixHandlers();
105: initURLTemplates(servletContext);
106: }
107:
108: /**
109: * This method will initialize all of the PrefixHandlers registered in the netui config.
110: * The prefix handlers are registered with ProcessPopulate and are typically implemented as
111: * public inner classes in the tags that require prefix handlers.
112: */
113: private static void initPrefixHandlers() {
114: PrefixHandlerConfig[] prefixHandlers = ConfigUtil.getConfig()
115: .getPrefixHandlers();
116: if (prefixHandlers == null) {
117: return;
118: }
119: for (int i = 0; i < prefixHandlers.length; i++) {
120: try {
121: Class prefixClass = Class.forName(prefixHandlers[i]
122: .getHandlerClass());
123: String name = prefixHandlers[i].getName();
124: if (name == null || name.equals("")) {
125: _log.warn("The name for the prefix handler '"
126: + prefixHandlers[i].getHandlerClass()
127: + "' must not be null");
128: continue;
129: }
130: Object o = prefixClass.newInstance();
131: if (!(o instanceof RequestParameterHandler)) {
132: _log
133: .warn("The class '"
134: + prefixHandlers[i]
135: .getHandlerClass()
136: + "' must be an instance of RequestParameterHandler");
137: continue;
138: }
139: ProcessPopulate.registerPrefixHandler(name,
140: (RequestParameterHandler) o);
141: } catch (ClassNotFoundException e) {
142: _log.warn("Class '"
143: + prefixHandlers[i].getHandlerClass()
144: + "' not found", e);
145: } catch (IllegalAccessException e) {
146: _log.warn("Illegal access on Class '"
147: + prefixHandlers[i].getHandlerClass() + "'", e);
148:
149: } catch (InstantiationException e) {
150: _log.warn("InstantiationException on Class '"
151: + prefixHandlers[i].getHandlerClass() + "'", e
152: .getCause());
153: }
154: }
155: }
156:
157: /**
158: * Creates a URLTemplatesFactory (may be container specific from the
159: * ServletContainerAdapter) and the the default TemplatedURLFormatter
160: * (registered in the netui config). These classes are used by the
161: * URLRewriterService.
162: */
163: private static void initURLTemplates(ServletContext servletContext) {
164: TemplatedURLFormatter formatter = TemplatedURLFormatter
165: .getTemplatedURLFormatter(servletContext);
166: if (formatter == null) {
167: // get the default template formatter class name from the config file
168: formatter = getTemplatedURLFormatter();
169:
170: assert formatter != null : "Found a non-null URL formatter";
171:
172: // set the TemplatedURLFormatter attribute on the context.
173: TemplatedURLFormatter.initServletContext(servletContext,
174: formatter);
175: }
176:
177: URLTemplatesFactory templatesFactory = URLTemplatesFactory
178: .getURLTemplatesFactory(servletContext);
179: if (templatesFactory == null) {
180: // URLTemplatesFactory has not been initialized,
181: // get a URLTemplatesFactory object from the containerAdapter.
182: templatesFactory = PageFlowUtils
183: .createURLTemplatesFactory(servletContext);
184:
185: // get the known/req tokens from the default formatter for the factory to use to verify templates
186: templatesFactory.setKnownTokens(formatter.getKnownTokens());
187: templatesFactory.setRequiredTokens(formatter
188: .getRequiredTokens());
189: templatesFactory.load(servletContext);
190:
191: // set the URLTemplatesFactory attribute on the context.
192: URLTemplatesFactory.initServletContext(servletContext,
193: templatesFactory);
194: }
195: }
196:
197: private static TemplatedURLFormatter getTemplatedURLFormatter() {
198: TemplatedURLFormatter formatter = null;
199:
200: // check for a default template formatter class name from the config file
201: UrlConfig urlConfig = ConfigUtil.getConfig().getUrlConfig();
202: if (urlConfig != null) {
203: String className = urlConfig
204: .getTemplatedUrlFormatterClass();
205: if (className != null) {
206: className = className.trim();
207:
208: // create an instance of the def template formatter class
209: ClassLoader cl = DiscoveryUtils.getClassLoader();
210:
211: try {
212: Class formatterClass = cl.loadClass(className);
213: if (!TemplatedURLFormatter.class
214: .isAssignableFrom(formatterClass)) {
215: _log
216: .error("The templated-url-formatter-class, "
217: + className
218: + ", does not extend TemplatedURLFormatter.");
219: } else {
220: formatter = (TemplatedURLFormatter) formatterClass
221: .newInstance();
222: }
223: } catch (ClassNotFoundException e) {
224: _log.error(
225: "Could not find templated-url-formatter-class "
226: + className, e);
227: } catch (InstantiationException e) {
228: _log.error(
229: "Could not instantiate templated-url-formatter-class "
230: + className, e);
231: } catch (IllegalAccessException e) {
232: _log.error(
233: "Could not instantiate templated-url-formatter-class "
234: + className, e);
235: }
236: }
237: }
238:
239: return formatter;
240: }
241:
242: private static class NetUIConfigResolver extends
243: XmlInputStreamResolver {
244:
245: private ServletContext _servletContext = null;
246:
247: private NetUIConfigResolver(ServletContext servletContext) {
248: _servletContext = servletContext;
249: }
250:
251: public String getResourcePath() {
252: return InternalConstants.NETUI_CONFIG_PATH;
253: }
254:
255: public InputStream getInputStream() {
256: return _servletContext
257: .getResourceAsStream(getResourcePath());
258: }
259: }
260: }
|