blob: 4109ade77031789eea154b200b8eaba1881d9407 [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 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;
}
}