blob: 480b122475c6382fd0d0568ebe5fb0ef3b459fdb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package flex.messaging.config;
import flex.messaging.LocalizedException;
import flex.messaging.util.Trace;
import flex.messaging.util.ClassUtil;
import javax.servlet.ServletConfig;
import java.io.File;
/**
* Manages which ConfigurationParser implementation will be
* used to read in the services configuration file and determines
* where the configuration file is located.
* <p>
* The default location of the configuration file is
* /WEB-INF/flex/services-config.xml, however this value can
* be specified in a servlet init-param &quot;services.configuration.file&quot;
* to the MessageBrokerServlet.
* </p>
* <p>
* The ConfigurationParser implementation can also be specified in
* a servlet init-param &quot;services.configuration.parser&quot; to
* the MessageBrokerServlet.
* </p>
*
* @see ConfigurationParser
*
*/
public class FlexConfigurationManager implements ConfigurationManager
{
private static final String DEFAULT_CONFIG_PATH = "/WEB-INF/flex/services-config.xml";
private String configurationPath = null;
private ConfigurationFileResolver configurationResolver = null;
private ConfigurationParser parser = null;
public MessagingConfiguration getMessagingConfiguration(ServletConfig servletConfig)
{
MessagingConfiguration config = new MessagingConfiguration();
if (servletConfig != null)
{
String serverInfo = servletConfig.getServletContext().getServerInfo();
config.getSecuritySettings().setServerInfo(serverInfo);
}
verifyMinimumJavaVersion();
parser = getConfigurationParser(servletConfig);
if (parser == null)
{
// "Unable to create a parser to load messaging configuration."
LocalizedException lme = new LocalizedException();
lme.setMessage(10138);
throw lme;
}
setupConfigurationPathAndResolver(servletConfig);
parser.parse(configurationPath, configurationResolver, config);
if (servletConfig != null)
{
config.getSystemSettings().setPaths(servletConfig.getServletContext());
}
return config;
}
public void reportTokens()
{
parser.reportTokens();
}
private ConfigurationParser getConfigurationParser(ServletConfig servletConfig)
{
ConfigurationParser parser = null;
Class parserClass;
String className = null;
// Check for Custom Parser Specification
if (servletConfig != null)
{
String p = servletConfig.getInitParameter("services.configuration.parser");
if (p != null)
{
className = p.trim();
try
{
parserClass = ClassUtil.createClass(className);
parser = (ConfigurationParser)parserClass.newInstance();
}
catch (Throwable t)
{
if (Trace.config)
{
Trace.trace("Could not load configuration parser as: " + className);
}
}
}
}
// Always try Sun JRE 1.4 / Apache Xalan Based Implementation first to
// avoid performance problems with Sun JRE 1.5 Based Implementation
if (parser == null)
{
try
{
ClassUtil.createClass("org.apache.xpath.CachedXPathAPI");
className = "flex.messaging.config.ApacheXPathServerConfigurationParser";
parserClass = ClassUtil.createClass(className);
parser = (ConfigurationParser)parserClass.newInstance();
}
catch (Throwable t)
{
if (Trace.config)
{
Trace.trace("Could not load configuration parser as: " + className);
}
}
}
// Try Sun JRE 1.5 Based Implementation
if (parser == null)
{
try
{
className = "flex.messaging.config.XPathServerConfigurationParser";
parserClass = ClassUtil.createClass(className);
// double-check, on some systems the above loads but the import classes don't
ClassUtil.createClass("javax.xml.xpath.XPathExpressionException");
parser = (ConfigurationParser)parserClass.newInstance();
}
catch (Throwable t)
{
if (Trace.config)
{
Trace.trace("Could not load configuration parser as: " + className);
}
}
}
if (Trace.config && parser != null)
{
Trace.trace("Services Configuration Parser: " + parser.getClass().getName());
}
return parser;
}
/**
* Sets up the configuration path and resolver objects.
* If no entry is specified in web.xml, assumed services-config.xml in the web application.
* If an entry is specified for windows starting with '/', it's assumed to be in the web application.
* If an entry is specified for windows not starting with '\', it's assumed to be on the local file system.
* If an entry is specified for non-windows starting with '/', we will first look in the web application
* then the the local file system.
*
* @param servletConfig configuration
*/
private void setupConfigurationPathAndResolver(ServletConfig servletConfig)
{
if (servletConfig != null)
{
String p = servletConfig.getInitParameter("services.configuration.file");
if ((p == null) || (p.trim().length() == 0))
{
// no entry specified in web.xml, always use default and ServletResourceResolver
configurationPath = DEFAULT_CONFIG_PATH;
configurationResolver = new ServletResourceResolver(servletConfig.getServletContext());
}
else
{
// an entry was specified in web.xml,
configurationPath = p.trim();
// If the uri starts with "classpath:" we need to use a different resolver.
if(configurationPath.startsWith("classpath:")) {
configurationResolver = new ClasspathResourceResolver();
} else {
// on windows, all paths starting with '/' should be available via the servlet resource resolver
// on other systems, you're not sure so try the servlet resource loader first it but don't throw an error,
// after that try using LocalFileResolver
boolean isWindows = File.separator.equals("\\");
boolean isServletResource = isWindows && configurationPath.startsWith("/");
if (isServletResource || !isWindows) {
ServletResourceResolver resolver = new ServletResourceResolver(servletConfig.getServletContext());
boolean available = resolver.isAvailable(configurationPath, isServletResource);
if (available) {
// it's available via the servlet resource loader
configurationResolver = resolver;
} else {
// it wasn't available via the servlet resource loader
configurationResolver = new LocalFileResolver(LocalFileResolver.SERVER);
}
} else {
// it's windows but seems to be specified as a file
configurationResolver = new LocalFileResolver(LocalFileResolver.SERVER);
}
}
}
}
// no entry specified in web.xml
else
{
ConfigurationException ce = new ConfigurationException();
ce.setMessage("missing ServletConfig object");
throw ce;
}
}
private void verifyMinimumJavaVersion() throws ConfigurationException
{
try
{
boolean minimum = false;
String version = System.getProperty("java.version");
String vendor = System.getProperty("java.vendor");
version = version.replace('.', ':');
version = version.replace('_', ':');
String[] split = version.split(":");
int first = Integer.parseInt(split[0]);
if (first > 1)
{
minimum = true;
}
else if (first == 1)
{
int second = Integer.parseInt(split[1]);
if (second > 4)
{
minimum = true;
}
else if (second == 4)
{
int third = Integer.parseInt(split[2]);
if (third > 2)
{
minimum = true;
}
else if (third == 2)
{
if ((vendor != null) && vendor.contains("Sun"))
{
// test at least 1.4.2_06 on Sun
int fourth = Integer.parseInt(split[3]);
if (fourth >= 6)
{
minimum = true;
}
}
else
{
// test at least 1.4.2 on non-Sun
minimum = true;
}
}
}
}
if (!minimum)
{
ConfigurationException cx = new ConfigurationException();
if ((vendor != null) && vendor.contains("Sun"))
{
// The minimum required Java version was not found. Please install JDK 1.4.2_06 or above. Current version is XX.
cx.setMessage(10139, new Object[] { System.getProperty("java.version")});
}
else
{
// The minimum required Java version was not found. Please install JDK 1.4.2 or above. Current version is XX.
cx.setMessage(10140, new Object[] { System.getProperty("java.version")});
}
throw cx;
}
}
catch (Throwable t)
{
if (t instanceof ConfigurationException)
{
throw ((ConfigurationException)t);
}
else
{
if (Trace.config)
{
Trace.trace("Could not verified required java version. version=" + System.getProperty("java.version"));
}
}
}
}
}