/* * © Copyright IBM Corp. 2012 * * Licensed 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 com.ibm.sbt.jslibrary.servlet; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ibm.commons.Platform; import com.ibm.commons.runtime.util.UrlUtil; import com.ibm.commons.util.StringUtil; import com.ibm.sbt.jslibrary.SBTEnvironment; import com.ibm.sbt.jslibrary.SBTEnvironmentFactory; /** * Wrapper object to encapsulate a request to the library servlet. * * @author priand * @author mwallace */ public class LibraryRequest { private boolean inited; protected HttpServletRequest httpRequest; protected HttpServletResponse httpResponse; protected String jsLib; protected String jsVersion; protected String toolkitUrl; protected String toolkitJsUrl; protected String serviceUrl; protected String libraryUrl; protected String iframeUrl; protected String toolkitExtUrl; protected String toolkitExtJsUrl; protected String jsLibraryUrl; protected boolean debug; protected boolean debugTransport; protected boolean mockTransport; protected boolean layer; protected boolean regPath; protected boolean initJs; protected SBTEnvironment environment; // List of the default endpoints being added by default. //public static final String INIT_JS = "/init.js"; public static final String DEFAULT_JSLIB = "dojo"; public static final String DEFAULT_VERSION = "1.4"; public static final Boolean DEFAULT_DEBUG = false; public static final Boolean DEFAULT_LAYER = false; public static final Boolean DEFAULT_REGPATH = true; public static final Boolean DEFAULT_INITJS = false; public static final Boolean DEFAULT_DEBUG_TRANSPORT = false; public static final Boolean DEFAULT_MOCK_TRANSPORT = false; // Definition of the servlet parameters (query string) /** * List of endpoints to generate */ public static final String PARAM_ENDPOINTS = "endpoints"; /** * List of client properties to generate */ public static final String PARAM_CLIENT_PROPERTIES = "props"; /** * List of client runtimes */ public static final String PARAM_CLIENT_RUNTIMES = "runtimes"; /** * Underlying library to be used, default is 'dojo' */ public static final String PARAM_JSLIB = "lib"; /** * Version of the library to use default is '1.4' */ public static final String PARAM_JSVERSION = "ver"; /** * Name of the environment to use */ public static final String PARAM_ENVIRONMENT = "env"; /** * Sets debug mode if true */ public static final String PARAM_DEBUG = "debug"; /** * Sets debug transport mode if true */ public static final String PARAM_DEBUG_TRANSPORT = "debugTransport"; /** * Sets mock transport mode if true */ public static final String PARAM_MOCK_TRANSPORT = "mockTransport"; /** * Sets javascript output for layer consumption */ public static final String PARAM_LAYER = "layer"; /** * Sets javascript output for aggregation with Connections' _js */ public static final String PARAM_REGPATH = "regPath"; /** * Sets */ public static final String PARAM_INITJS = "initJs"; /** * Enables/Disables the aggregator (default is false) */ public static final String PARAM_AGGREGATOR = "aggregator"; /** * List of modules/layers to load, '*' means everything */ public static final String PARAM_MODULE = "modules"; /** * The context in which the library is being loaded into. This is an * optional param on the request. Currently the only valid value is * <code>gadget</code>. * * Refer to GADGET_CONTEXT */ public static final String PARAM_CONTEXT = "context"; /** * List of string tokens that can be replaced dynamically */ public static final String[] REPLACE_VALUES = { "%local_server%", "%local_application%", "%request_url%", "%context_path%" }; static final String sourceClass = LibraryRequest.class.getName(); static final Logger logger = Logger.getLogger(sourceClass); /** * Default constructor */ public LibraryRequest() { } /** * * @param req * @param resp */ public LibraryRequest(HttpServletRequest req, HttpServletResponse resp) { this.httpRequest = req; this.httpResponse = resp; } /** * Initialise the LibraryRequest * * @param params * * @throws ServletException * @throws IOException */ public void init(LibraryRequestParams params) throws LibraryException { try { String[] replaces = { getServerUrl(params), getContextUrl(params), getRequestUrl(params), getContextPath(params) }; this.toolkitUrl = replace(params.getToolkitUrl(), REPLACE_VALUES, replaces); this.toolkitJsUrl = replace(params.getToolkitJsUrl(), REPLACE_VALUES, replaces); this.toolkitExtUrl = replace(params.getToolkitExtUrl(), REPLACE_VALUES, replaces); this.toolkitExtJsUrl = replace(params.getToolkitExtJsUrl(), REPLACE_VALUES, replaces); this.serviceUrl = replace(params.getServiceUrl(), REPLACE_VALUES, replaces); this.libraryUrl = replace(params.getLibraryUrl(), REPLACE_VALUES, replaces); this.jsLibraryUrl = replace(params.getJsLibraryUrl(), REPLACE_VALUES, replaces); this.iframeUrl = replace(params.getIframeUrl(), REPLACE_VALUES, replaces); readFromRequest(params, params.getEnvironment()); inited = true; if (logger.isLoggable(Level.FINE)) { logger.fine("Created library request: " + toString()); } } catch (Exception e) { throw new LibraryException("Error initialising library request caused by: "+e.getMessage(), e); } } /** * @return the inited */ public boolean isInited() { return inited; } /** * @return the httpRequest */ public HttpServletRequest getHttpRequest() { return httpRequest; } /** * @return the httpResponse */ public HttpServletResponse getHttpResponse() { return httpResponse; } /** * * @param name * @return a parameter */ public String getParameter(String name) { if (httpRequest != null) { return httpRequest.getParameter(name); } return null; } /** * * @return true, if there is a proxy domain */ public boolean isProxyDomain() { //TODO: Always returns True. This code is not used. return true; } /** * * @return the service url */ public String getServiceUrl() { return serviceUrl; } /** * * @return the library url */ public String getLibraryUrl() { return libraryUrl; } /** * * @return the js library url */ public String getJsLibraryUrl() { return jsLibraryUrl; } /** * * @return use Iframe */ public boolean useIFrame() { //TODO: Always returns false. This code is not used. return false; } /** * @param initJs the initJs to set */ public void setInitJs(boolean initJs) { this.initJs = initJs; } /** * @return the js */ public boolean isInitJs() { return initJs; } /** * * @return if debug */ public boolean isDebug() { return debug; } /** * @param debug the debug to set */ public void setDebug(boolean debug) { this.debug = debug; } /** * * @return the layer */ public boolean isLayer() { return layer; } /** * * @return registration path */ public boolean isRegPath() { return regPath; } /** * @param regPath the regPath to set */ public void setRegPath(boolean regPath) { this.regPath = regPath; } /** * * @return debug transport */ public boolean isDebugTransport() { return debugTransport; } /** * * @return mocktransport */ public boolean isMockTransport() { return mockTransport; } /** * * @return the iframe url */ public String getIFrameUrl() { return iframeUrl; } /** * @return the jsLib */ public String getJsLib() { return jsLib; } /** * @return the jsVersion */ public String getJsVersion() { return jsVersion; } /** * @return the toolkit URL */ public String getToolkitUrl() { return toolkitUrl; } /** * @return the toolkit JavaScript URL */ public String getToolkitJsUrl() { return toolkitJsUrl; } /** * @return the toolkit extention URL */ public String getToolkitExtUrl() { return toolkitExtUrl; } /** * @return the toolkit extention URL */ public String getToolkitExtJsUrl() { return toolkitExtJsUrl; } /** * @return the environment */ public SBTEnvironment getEnvironment() { return environment; } /** * Return the specified header * * @return the header */ public String getHeader(String name) { return httpRequest.getHeader(name); } /** * @return the server url */ protected String getServerUrl(LibraryRequestParams params) { if (httpRequest != null) { return UrlUtil.getServerUrl(httpRequest); } else { return params.getServerUrl(); } } /** * @return the context url */ protected String getContextUrl(LibraryRequestParams params) { if (httpRequest != null) { return UrlUtil.getContextUrl(httpRequest); } else { return params.getContextUrl(); } } /** * @return the context path */ protected String getContextPath(LibraryRequestParams params) { if (httpRequest != null) { return httpRequest.getContextPath(); } else { return params.getContextPath(); } } /** * @return the request url */ protected String getRequestUrl(LibraryRequestParams params) { if (httpRequest != null) { return UrlUtil.getRequestUrl(httpRequest); } else { return params.getRequestUrl(); } } /** * * @param params * @param defaultEnvironment * * @throws ServletException * @throws IOException */ protected void readFromRequest(LibraryRequestParams params, SBTEnvironment defaultEnvironment) throws ServletException, IOException { jsLib = readString(params, PARAM_JSLIB, getDefaultJsLib()); jsVersion = readString(params, PARAM_JSVERSION, DEFAULT_JSLIB.equals(jsLib) ? getDefaultJsVersion() : ""); debug = Boolean.parseBoolean(readString(params, PARAM_DEBUG, getDefaultDebug())); layer = Boolean.parseBoolean(readString(params, PARAM_LAYER, getDefaultLayer())); regPath = Boolean.parseBoolean(readString(params, PARAM_REGPATH, getDefaultRegPath())); initJs = Boolean.parseBoolean(readString(params, PARAM_INITJS, getDefaultInitJs())); debugTransport = Boolean.parseBoolean(readString(params, PARAM_DEBUG_TRANSPORT, getDefaultDebugTransport())); mockTransport = Boolean.parseBoolean(readString(params, PARAM_MOCK_TRANSPORT, getDefaultMockTransport())); String environmentName = readString(params, PARAM_ENVIRONMENT, null); if (!StringUtil.isEmpty(environmentName)) { SBTEnvironment parentEnvironment = SBTEnvironmentFactory.get(environmentName); if (parentEnvironment == null) { String message = MessageFormat.format("Unable to load environment: {0}", environmentName); throw new ServletException(message); } parentEnvironment.prepareEndpoints(); environment = new RequestEnvironment(params, parentEnvironment); } if (environment == null) { if(defaultEnvironment != null) { defaultEnvironment.prepareEndpoints(); } environment = new RequestEnvironment(params, defaultEnvironment); } } protected String getPathInfo(LibraryRequestParams params) { if (httpRequest != null) { return httpRequest.getPathInfo(); } else { return params.getPathInfo(); } } protected String getDefaultJsLib() { return DEFAULT_JSLIB; } protected String getDefaultJsVersion() { return DEFAULT_VERSION; } protected String getDefaultDebug() { return DEFAULT_DEBUG.toString(); } protected String getDefaultLayer() { return DEFAULT_LAYER.toString(); } protected String getDefaultRegPath() { return DEFAULT_REGPATH.toString(); } protected String getDefaultInitJs() { return DEFAULT_INITJS.toString(); } protected String getDefaultDebugTransport() { return DEFAULT_DEBUG_TRANSPORT.toString(); } protected String getDefaultMockTransport() { return DEFAULT_MOCK_TRANSPORT.toString(); } /** * Read a parameter from the request and return the value if it's a valid * value i.e. not null and not an empty string. Otherwise return the default * value. * * @param req * @param paramName * @param defValue * * @return the value of the given parameter * * @throws ServletException * @throws IOException */ private String readString(LibraryRequestParams params, String paramName, String defaultValue) { String val = null; if (httpRequest != null) { val = httpRequest.getParameter(paramName); } else { val = params.getParameter(paramName); } if (val != null && val.length() > 0) { return val; } return defaultValue; } /** * Replace any of the listed values with the specified replacement in the source string. * * @param source * @param values * @param replace * @return string with updated value */ private String replace(String source, String[] values, String[] replaces) { if (StringUtil.isEmpty(source) || values == null || replaces == null) { return ""; //$NON-NLS-1$ } for (int i=0; i<values.length; i++) { source = StringUtil.replace(source, values[i], replaces[i]); } return source; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append("jsLib=").append(jsLib); sb.append(";jsVersion=").append(jsVersion); sb.append(";environment=").append(environment); sb.append(";toolkitUrl=").append(toolkitUrl); sb.append(";toolkitJsUrl=").append(toolkitJsUrl); sb.append(";jsLibraryUrl=").append(jsLibraryUrl); sb.append(";layer=").append(layer); sb.append(";regPath=").append(regPath); sb.append("}"); return sb.toString(); } /** * Class representing the SBTEnvironment for this request * * @author mwallace */ class RequestEnvironment extends SBTEnvironment { private SBTEnvironment parent; /** * * @param parent */ RequestEnvironment(LibraryRequestParams params, SBTEnvironment parent) { this.parent = parent; String endpointsStr = readString(params, PARAM_ENDPOINTS, null); if (!StringUtil.isEmpty(endpointsStr)) { Endpoint[] requestEndpoints = parseEndpoints(endpointsStr); if (requestEndpoints != null && requestEndpoints.length > 0) { Endpoint[] defaultEndpoints = parent.getEndpointsArray(); List<Endpoint> endpoints = new ArrayList<Endpoint>(); for (int i = 0; i < requestEndpoints.length; i++) { endpoints.add(requestEndpoints[i]); } for (int i = 0; i < defaultEndpoints.length; i++) { endpoints.add(defaultEndpoints[i]); } setEndpointsArray(endpoints.toArray(new Endpoint[endpoints.size()])); } } String propertiesStr = readString(params, PARAM_CLIENT_PROPERTIES, null); if (!StringUtil.isEmpty(propertiesStr)) { try { Property[] requestProperties = parseProperties(propertiesStr); if (requestProperties != null && requestProperties.length > 0) { Property[] defaultProperties = parent.getPropertiesArray(); List<Property> properties = new ArrayList<Property>(); for (int i = 0; i < requestProperties.length; i++) { properties.add(requestProperties[i]); } for (int i = 0; i < defaultProperties.length; i++) { properties.add(defaultProperties[i]); } setPropertiesArray(properties.toArray(new Property[properties.size()])); } } catch (IOException ex) { Platform.getInstance().log(ex); } } String runtimesStr = readString(params, PARAM_CLIENT_RUNTIMES, null); if(!StringUtil.isEmpty(runtimesStr)){ setRuntimes(runtimesStr); } } /* * (non-Javadoc) * * @see com.ibm.sbt.jslibrary.SBTEnvironment#getName() */ @Override public String getName() { return parent.getName(); } /* * (non-Javadoc) * * @see com.ibm.sbt.jslibrary.SBTEnvironment#getEndpointsArray() */ @Override public Endpoint[] getEndpointsArray() { Endpoint[] endpoints = super.getEndpointsArray(); if (endpoints != null) { return endpoints; } return parent.getEndpointsArray(); } /* * (non-Javadoc) * * @see com.ibm.sbt.jslibrary.SBTEnvironment#getPropertiesArray() */ @Override public Property[] getPropertiesArray() { Property[] properties = super.getPropertiesArray(); if (properties != null) { return properties; } return parent.getPropertiesArray(); } /* * (non-Javadoc) * * @see * com.ibm.sbt.jslibrary.SBTEnvironment#getPropertyByName(java.lang. * String) */ @Override public Property getPropertyByName(String name) { Property property = super.getPropertyByName(name); if (property != null) { return property; } return parent.getPropertyByName(name); } /* * (non-Javadoc) * * @see * com.ibm.sbt.jslibrary.SBTEnvironment#getPropertyValueByName(java. * lang.String) */ @Override public String getPropertyValueByName(String name) { String value = super.getPropertyValueByName(name); if (value != null) { return value; } return parent.getPropertyValueByName(name); } } }