| /******************************************************************************* |
| * 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 org.apache.ofbiz.webapp.stats; |
| |
| import java.net.InetAddress; |
| import java.sql.Timestamp; |
| import java.util.Arrays; |
| import java.util.Locale; |
| |
| import javax.servlet.http.Cookie; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.servlet.http.HttpSession; |
| |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.UtilProperties; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.DelegatorFactory; |
| import org.apache.ofbiz.entity.GenericEntityException; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entity.model.ModelEntity; |
| import org.apache.ofbiz.entity.util.EntityQuery; |
| import org.apache.ofbiz.entity.util.EntityUtilProperties; |
| |
| /** |
| * Handles saving and maintaining visit information |
| */ |
| public class VisitHandler { |
| // Debug MODULE name |
| private static final String MODULE = VisitHandler.class.getName(); |
| |
| public static final String VISITOR_COOKIE_NAME = "OFBiz.Visitor"; |
| |
| protected static final InetAddress ADDRESS; |
| static { |
| InetAddress tmpAddress = null; |
| try { |
| tmpAddress = InetAddress.getLocalHost(); |
| } catch (java.net.UnknownHostException e) { |
| Debug.logError("Unable to get server's internet ADDRESS: " + e.toString(), MODULE); |
| } |
| ADDRESS = tmpAddress; |
| } |
| |
| public static void setUserLogin(HttpSession session, GenericValue userLogin, boolean userCreated) { |
| if (userLogin == null) return; |
| ModelEntity modelUserLogin = userLogin.getModelEntity(); |
| |
| GenericValue visitor = (GenericValue) session.getAttribute("visitor"); |
| if (visitor != null) { |
| visitor.set("userLoginId", userLogin.get("userLoginId")); |
| if (modelUserLogin.isField("partyId")) { |
| visitor.set("partyId", userLogin.get("partyId")); |
| } |
| try { |
| visitor.store(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Could not update visitor: ", MODULE); |
| } |
| } |
| |
| GenericValue visit = getVisit(session); |
| if (visit != null) { |
| visit.set("userLoginId", userLogin.get("userLoginId")); |
| if (modelUserLogin.isField("partyId")) { |
| visit.set("partyId", userLogin.get("partyId")); |
| } |
| visit.set("userCreated", userCreated); |
| |
| // make sure the visitorId is still in place |
| if (visitor != null) { |
| visit.set("visitorId", visitor.get("visitorId")); |
| } |
| |
| try { |
| visit.store(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Could not update visit: ", MODULE); |
| } |
| } |
| } |
| |
| public static String getVisitId(HttpSession session) { |
| GenericValue visit = getVisit(session); |
| if (visit != null) { |
| return visit.getString("visitId"); |
| } else { |
| return null; |
| } |
| } |
| |
| /** Get the visit from the session, or create if missing */ |
| public static GenericValue getVisit(HttpSession session) { |
| // this defaults to true: ie if anything but "false" it will be true |
| if (!UtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist.visit", "false")) { |
| GenericValue visit = (GenericValue) session.getAttribute("visit"); |
| if (visit == null) { |
| synchronized (session) { |
| visit = (GenericValue) session.getAttribute("visit"); |
| if (visit == null) { |
| Delegator delegator = null; |
| |
| // first try the session attribute delegatorName |
| String delegatorName = (String) session.getAttribute("delegatorName"); |
| if (UtilValidate.isNotEmpty(delegatorName)) { |
| delegator = DelegatorFactory.getDelegator(delegatorName); |
| } |
| |
| // then try the ServletContext attribute delegator, should always be there... |
| if (delegator == null) { |
| delegator = (Delegator) session.getServletContext().getAttribute("delegator"); |
| } |
| |
| if (delegator == null) { |
| Debug.logError("Could not find delegator with delegatorName [" + delegatorName |
| + "] in session, or a delegator attribute in the ServletContext, not creating Visit entity", MODULE); |
| } else { |
| String webappName = (String) session.getAttribute("_WEBAPP_NAME_"); |
| Locale initialLocaleObj = (Locale) session.getAttribute("_CLIENT_LOCALE_"); |
| String initialRequest = (String) session.getAttribute("_CLIENT_REQUEST_"); |
| String initialReferrer = (String) session.getAttribute("_CLIENT_REFERER_"); |
| String initialUserAgent = (String) session.getAttribute("_CLIENT_USER_AGENT_"); |
| |
| String initialLocale = initialLocaleObj != null ? initialLocaleObj.toString() : ""; |
| |
| if (UtilValidate.isEmpty(webappName)) { |
| Debug.logInfo(new Exception(), "The webappName was empty, somehow the initial request settings were missing.", |
| MODULE); |
| } |
| |
| visit = delegator.makeValue("Visit"); |
| visit.set("sessionId", session.getId()); |
| visit.set("fromDate", new Timestamp(session.getCreationTime())); |
| |
| visit.set("initialLocale", initialLocale); |
| if (initialRequest != null) { |
| visit.set("initialRequest", initialRequest.length() > 2000 ? initialRequest.substring(0, 1999) |
| : initialRequest); |
| } |
| if (initialReferrer != null) { |
| visit.set("initialReferrer", initialReferrer.length() > 2000 ? initialReferrer.substring(0, 1999) |
| : initialReferrer); |
| } |
| if (initialUserAgent != null) { |
| visit.set("initialUserAgent", initialUserAgent.length() > 250 ? initialUserAgent.substring(0, 250) |
| : initialUserAgent); |
| } |
| visit.set("webappName", webappName); |
| if (UtilProperties.propertyValueEquals("serverstats", "stats.proxy.enabled", "true")) { |
| visit.set("clientIpAddress", session.getAttribute("_CLIENT_FORWARDED_FOR_")); |
| } else { |
| visit.set("clientIpAddress", session.getAttribute("_CLIENT_REMOTE_ADDR_")); |
| } |
| visit.set("clientHostName", session.getAttribute("_CLIENT_REMOTE_HOST_")); |
| visit.set("clientUser", session.getAttribute("_CLIENT_REMOTE_USER_")); |
| |
| // get the visitorId |
| GenericValue visitor = (GenericValue) session.getAttribute("visitor"); |
| if (visitor != null) { |
| String visitorId = visitor.getString("visitorId"); |
| // sometimes these values get stale, so check it before we use it |
| try { |
| GenericValue checkVisitor = EntityQuery.use(delegator).from("Visitor").where("visitorId", visitorId).queryOne(); |
| if (checkVisitor == null) { |
| GenericValue newVisitor = delegator.create("Visitor", "visitorId", visitorId); |
| session.setAttribute("visitor", newVisitor); |
| } |
| visit.set("visitorId", visitorId); |
| } catch (GenericEntityException e) { |
| Debug.logWarning("Problem checking the visitorId: " + e.toString(), MODULE); |
| } |
| } |
| // get localhost ip ADDRESS and hostname to store |
| if (ADDRESS != null) { |
| visit.set("serverIpAddress", ADDRESS.getHostAddress()); |
| visit.set("serverHostName", ADDRESS.getHostName()); |
| } |
| try { |
| visit = delegator.createSetNextSeqId(visit); |
| session.setAttribute("visit", visit); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Could not create new visit:", MODULE); |
| visit = null; |
| } |
| } |
| } |
| } |
| } |
| if (visit == null) { |
| Debug.logWarning("Could not find or create the visit...", MODULE); |
| } |
| return visit; |
| } |
| return null; |
| } |
| public static GenericValue getVisitor(HttpServletRequest request, HttpServletResponse response) { |
| // this defaults to true: ie if anything but "false" it will be true |
| Delegator delegator = (Delegator) request.getAttribute("delegator"); |
| if (!EntityUtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist.visitor", "false", delegator)) { |
| HttpSession session = request.getSession(); |
| GenericValue visitor = (GenericValue) session.getAttribute("visitor"); |
| if (visitor == null) { |
| synchronized (session) { |
| visitor = (GenericValue) session.getAttribute("visitor"); |
| if (visitor == null) { |
| |
| String delegatorName = (String) session.getAttribute("delegatorName"); |
| if (delegator == null && UtilValidate.isNotEmpty(delegatorName)) { |
| delegator = DelegatorFactory.getDelegator(delegatorName); |
| } |
| |
| if (delegator == null) { |
| Debug.logError("Could not find delegator in request or with delegatorName [" + delegatorName |
| + "] in session, not creating/getting Visitor entity", MODULE); |
| } else { |
| // first try to get the current ID from the visitor cookie |
| String cookieVisitorId = null; |
| Cookie[] cookies = request.getCookies(); |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("Cookies:" + String.join(",", Arrays.stream(cookies).toArray(String[]::new)), MODULE); |
| } |
| if (cookies != null) { |
| for (int i = 0; i < cookies.length; i++) { |
| if (cookies[i].getName().equals(VISITOR_COOKIE_NAME)) { |
| cookieVisitorId = cookies[i].getValue(); |
| break; |
| } |
| } |
| } |
| |
| if (Debug.infoOn()) { |
| Debug.logInfo("Found visitorId [" + cookieVisitorId + "] in cookie", MODULE); |
| } |
| |
| if (UtilValidate.isEmpty(cookieVisitorId)) { |
| // no visitor cookie? create visitor and send back cookie too |
| visitor = delegator.makeValue("Visitor"); |
| try { |
| delegator.createSetNextSeqId(visitor); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Could not create new visitor:", MODULE); |
| visitor = null; |
| } |
| } else { |
| try { |
| visitor = EntityQuery.use(delegator).from("Visitor").where("visitorId", cookieVisitorId).queryOne(); |
| if (visitor == null) { |
| // looks like we have an ID that doesn't exist in our database, so we'll create a new one |
| visitor = delegator.makeValue("Visitor"); |
| visitor = delegator.createSetNextSeqId(visitor); |
| if (Debug.infoOn()) { |
| String visitorId = visitor != null ? visitor.getString("visitorId") : "empty visitor"; |
| Debug.logInfo("The visitorId [" + cookieVisitorId |
| + "] found in cookie was invalid, creating new Visitor with ID [" + visitorId + "]", MODULE); |
| } |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, "Error finding visitor with ID from cookie: " + cookieVisitorId, MODULE); |
| visitor = null; |
| } |
| } |
| } |
| |
| if (visitor != null) { |
| // we got one, and it's a new one since it was null before |
| session.setAttribute("visitor", visitor); |
| |
| // create the cookie and send it back, this may be done over and over, in effect frequently refreshing the cookie |
| Cookie visitorCookie = new Cookie(VISITOR_COOKIE_NAME, visitor.getString("visitorId")); |
| visitorCookie.setMaxAge(60 * 60 * 24 * 365); |
| visitorCookie.setPath("/"); |
| visitorCookie.setSecure(true); |
| visitorCookie.setHttpOnly(true); |
| response.addCookie(visitorCookie); |
| } |
| } |
| } |
| } |
| if (visitor == null) { |
| Debug.logWarning(new Exception(), "Could not find or create the visitor...", MODULE); |
| } |
| return visitor; |
| } |
| return null; |
| } |
| } |