Java tutorial
/* * #%L * BroadleafCommerce Common Libraries * %% * Copyright (C) 2009 - 2013 Broadleaf Commerce * %% * 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. * #L% */ package org.broadleafcommerce.common.web; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.broadleafcommerce.common.crossapp.service.CrossAppAuthService; import org.broadleafcommerce.common.sandbox.dao.SandBoxDao; import org.broadleafcommerce.common.sandbox.domain.SandBox; import org.broadleafcommerce.common.sandbox.domain.SandBoxType; import org.broadleafcommerce.common.site.domain.Site; import org.broadleafcommerce.common.time.FixedTimeSource; import org.broadleafcommerce.common.time.SystemTime; import org.broadleafcommerce.common.util.BLCRequestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; import java.text.ParseException; import java.util.Calendar; import java.util.Date; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; /** * Responsible for determining the SandBox to use for the current request. * SandBox's are used to store a user's changes to products, content-items, etc. * until they are ready to be pushed to production. * * If a request is being served with a SandBox parameter, it indicates that the user * wants to see the site as if their changes were applied. * * @author bpolster */ @Component("blSandBoxResolver") public class BroadleafSandBoxResolverImpl implements BroadleafSandBoxResolver { private final Log LOG = LogFactory.getLog(BroadleafSandBoxResolverImpl.class); /** * Property used to disable sandbox mode. Some implementations will want to * turn off sandboxes in production. */ protected Boolean sandBoxPreviewEnabled = true; // Request Parameters and Attributes for Sandbox Mode properties - mostly values to manage dates. private static String SANDBOX_DATE_TIME_VAR = "blSandboxDateTime"; private static final FastDateFormat CONTENT_DATE_FORMATTER = FastDateFormat.getInstance("yyyyMMddHHmm"); private static final FastDateFormat CONTENT_DATE_DISPLAY_FORMATTER = FastDateFormat.getInstance("MM/dd/yyyy"); private static final FastDateFormat CONTENT_DATE_DISPLAY_HOURS_FORMATTER = FastDateFormat.getInstance("h"); private static final FastDateFormat CONTENT_DATE_DISPLAY_MINUTES_FORMATTER = FastDateFormat.getInstance("mm"); private static final FastDateFormat CONTENT_DATE_PARSE_FORMAT = FastDateFormat .getInstance("MM/dd/yyyy hh:mm aa"); private static String SANDBOX_DATE_TIME_RIBBON_OVERRIDE_PARAM = "blSandboxDateTimeRibbonOverride"; private static final String SANDBOX_DISPLAY_DATE_TIME_DATE_PARAM = "blSandboxDisplayDateTimeDate"; private static final String SANDBOX_DISPLAY_DATE_TIME_HOURS_PARAM = "blSandboxDisplayDateTimeHours"; private static final String SANDBOX_DISPLAY_DATE_TIME_MINUTES_PARAM = "blSandboxDisplayDateTimeMinutes"; private static final String SANDBOX_DISPLAY_DATE_TIME_AMPM_PARAM = "blSandboxDisplayDateTimeAMPM"; /** * Request attribute to store the current sandbox */ public static String SANDBOX_VAR = "blSandbox"; @Resource(name = "blSandBoxDao") private SandBoxDao sandBoxDao; @Autowired(required = false) @Qualifier("blCrossAppAuthService") protected CrossAppAuthService crossAppAuthService; /** * Determines the current sandbox based on other parameters on the request such as * the blSandBoxId parameters. * * If the {@link #getSandBoxPreviewEnabled()}, then this method will not return a user * SandBox. * */ @Override public SandBox resolveSandBox(HttpServletRequest request, Site site) { return resolveSandBox(new ServletWebRequest(request), site); } @Override public SandBox resolveSandBox(WebRequest request, Site site) { Long previousSandBoxId = null; if (BLCRequestUtils.isOKtoUseSession(request)) { previousSandBoxId = (Long) request.getAttribute(SANDBOX_ID_VAR, WebRequest.SCOPE_GLOBAL_SESSION); } SandBox currentSandbox = null; if (!sandBoxPreviewEnabled) { if (LOG.isTraceEnabled()) { LOG.trace("Sandbox preview disabled. Setting sandbox to production"); } request.setAttribute(SANDBOX_VAR, currentSandbox, WebRequest.SCOPE_REQUEST); } else if (crossAppAuthService != null && !crossAppAuthService.isAuthedFromAdmin()) { if (LOG.isInfoEnabled()) { LOG.info("Sandbox preview attempted without authentication"); } request.setAttribute(SANDBOX_VAR, currentSandbox, WebRequest.SCOPE_REQUEST); } else if (crossAppAuthService != null && crossAppAuthService.hasCsrPermission()) { if (LOG.isInfoEnabled()) { LOG.info("Sandbox preview attempted in CSR mode"); } request.setAttribute(SANDBOX_VAR, currentSandbox, WebRequest.SCOPE_REQUEST); } else { Long sandboxId = null; // Clear the sandBox - second parameter is to support legacy implementations. if ((request.getParameter("blClearSandBox") == null) && (request.getParameter("blSandboxDateTimeRibbonProduction") == null)) { sandboxId = lookupSandboxId(request); } else { if (LOG.isTraceEnabled()) { LOG.trace("Removing sandbox from session."); } if (BLCRequestUtils.isOKtoUseSession(request)) { request.removeAttribute(SANDBOX_DATE_TIME_VAR, WebRequest.SCOPE_GLOBAL_SESSION); request.removeAttribute(SANDBOX_ID_VAR, WebRequest.SCOPE_GLOBAL_SESSION); } SystemTime.resetLocalTimeSource(); } if (sandboxId != null) { if (previousSandBoxId != null && !previousSandBoxId.equals(sandboxId)) { request.setAttribute(BroadleafRequestProcessor.REPROCESS_PARAM_NAME, true, WebRequest.SCOPE_REQUEST); } currentSandbox = sandBoxDao.retrieve(sandboxId); request.setAttribute(SANDBOX_VAR, currentSandbox, WebRequest.SCOPE_REQUEST); if (currentSandbox != null && !SandBoxType.PRODUCTION.equals(currentSandbox.getSandBoxType())) { setContentTime(request); } } // if (currentSandbox == null && site != null) { // currentSandbox = site.getProductionSandbox(); // } } if (LOG.isTraceEnabled()) { if (currentSandbox != null) { LOG.trace("Serving request using sandbox: " + currentSandbox); } else { LOG.trace("Serving request without a sandbox."); } } Date currentSystemDateTime = SystemTime.asDate(true); Calendar sandboxDateTimeCalendar = Calendar.getInstance(); sandboxDateTimeCalendar.setTime(currentSystemDateTime); request.setAttribute(SANDBOX_DISPLAY_DATE_TIME_DATE_PARAM, CONTENT_DATE_DISPLAY_FORMATTER.format(currentSystemDateTime), WebRequest.SCOPE_REQUEST); request.setAttribute(SANDBOX_DISPLAY_DATE_TIME_HOURS_PARAM, CONTENT_DATE_DISPLAY_HOURS_FORMATTER.format(currentSystemDateTime), WebRequest.SCOPE_REQUEST); request.setAttribute(SANDBOX_DISPLAY_DATE_TIME_MINUTES_PARAM, CONTENT_DATE_DISPLAY_MINUTES_FORMATTER.format(currentSystemDateTime), WebRequest.SCOPE_REQUEST); request.setAttribute(SANDBOX_DISPLAY_DATE_TIME_AMPM_PARAM, sandboxDateTimeCalendar.get(Calendar.AM_PM), WebRequest.SCOPE_REQUEST); return currentSandbox; } /** * If another filter has already set the language as a request attribute, that will be honored. * Otherwise, the request parameter is checked followed by the session attribute. * * @param request * @return */ private Long lookupSandboxId(WebRequest request) { String sandboxIdStr = request.getParameter(SANDBOX_ID_VAR); Long sandboxId = null; if (sandboxIdStr != null) { try { sandboxId = Long.valueOf(sandboxIdStr); if (LOG.isTraceEnabled()) { LOG.trace("SandboxId found on request " + sandboxId); } } catch (NumberFormatException nfe) { LOG.warn("blcSandboxId parameter could not be converted into a Long", nfe); } } if (BLCRequestUtils.isOKtoUseSession(request)) { if (sandboxId == null) { // check the session sandboxId = (Long) request.getAttribute(SANDBOX_ID_VAR, WebRequest.SCOPE_GLOBAL_SESSION); if (LOG.isTraceEnabled()) { if (sandboxId != null) { LOG.trace("SandboxId found in session " + sandboxId); } } } else { request.setAttribute(SANDBOX_ID_VAR, sandboxId, WebRequest.SCOPE_GLOBAL_SESSION); } } return sandboxId; } /** * Allows a user in SandBox mode to override the current time and date being used by the system. * * @param request */ private void setContentTime(WebRequest request) { String sandboxDateTimeParam = request.getParameter(SANDBOX_DATE_TIME_VAR); if (!sandBoxPreviewEnabled) { sandboxDateTimeParam = null; } Date overrideTime = null; try { if (request.getParameter(SANDBOX_DATE_TIME_RIBBON_OVERRIDE_PARAM) != null) { overrideTime = readDateFromRequest(request); } else if (sandboxDateTimeParam != null) { if (LOG.isDebugEnabled()) { LOG.debug("Setting date/time using " + sandboxDateTimeParam); } overrideTime = CONTENT_DATE_FORMATTER.parse(sandboxDateTimeParam); } } catch (ParseException e) { LOG.debug(e); } if (BLCRequestUtils.isOKtoUseSession(request)) { if (overrideTime == null) { overrideTime = (Date) request.getAttribute(SANDBOX_DATE_TIME_VAR, WebRequest.SCOPE_GLOBAL_SESSION); } else { if (LOG.isDebugEnabled()) { LOG.debug("Setting date-time for sandbox mode to " + overrideTime + " for sandboxDateTimeParam = " + sandboxDateTimeParam); } request.setAttribute(SANDBOX_DATE_TIME_VAR, overrideTime, WebRequest.SCOPE_GLOBAL_SESSION); } } if (overrideTime != null) { FixedTimeSource ft = new FixedTimeSource(overrideTime.getTime()); SystemTime.setLocalTimeSource(ft); } else { SystemTime.resetLocalTimeSource(); } } private Date readDateFromRequest(WebRequest request) throws ParseException { String date = request.getParameter(SANDBOX_DISPLAY_DATE_TIME_DATE_PARAM); String minutes = request.getParameter(SANDBOX_DISPLAY_DATE_TIME_MINUTES_PARAM); String hours = request.getParameter(SANDBOX_DISPLAY_DATE_TIME_HOURS_PARAM); String ampm = request.getParameter(SANDBOX_DISPLAY_DATE_TIME_AMPM_PARAM); if (StringUtils.isEmpty(minutes)) { minutes = Integer.toString(SystemTime.asCalendar().get(Calendar.MINUTE)); } if (StringUtils.isEmpty(hours)) { hours = Integer.toString(SystemTime.asCalendar().get(Calendar.HOUR_OF_DAY)); } String dateString = date + " " + hours + ":" + minutes + " " + ampm; if (LOG.isDebugEnabled()) { LOG.debug("Setting date/time using " + dateString); } Date parsedDate = CONTENT_DATE_PARSE_FORMAT.parse(dateString); return parsedDate; } /** * Sets whether or not the site can be viewed in preview mode. * @return */ public Boolean getSandBoxPreviewEnabled() { return sandBoxPreviewEnabled; } public void setSandBoxPreviewEnabled(Boolean sandBoxPreviewEnabled) { this.sandBoxPreviewEnabled = sandBoxPreviewEnabled; } }