private void initDevices(ServletContext ctx) {
    // Context-shared PMF.
    PersistenceManager pm = DBHelper.getPMF(ctx).getPersistenceManager();

    try {
      devices = DeviceInfo.getDeviceInfoForUserEmail(pm, userEmail);
      // cleanup for multi-device
      /*if (devices.size() > 1) {
      // Make sure there is no 'bare' registration
      // Keys are sorted - check the first
      DeviceInfo first = devices.get(0);
      Key oldKey = first.getKey();
      if (oldKey.toString().indexOf("#") < 0) {
          log.warning("Removing old-style key " + oldKey.toString());
          // multiple devices, first is old-style.
          devices.remove(0);
          pm.deletePersistent(first);
      }
         }*/
      log.log(
          Level.INFO,
          "RequestInfo:initDevices() : loading devices "
              + devices.size()
              + " for user = "******"RequestInfo:initDevices() : Error loading registrations ", e);
    } finally {
      pm.close();
    }
  }
  // We need to iterate again - can be avoided with a query.
  // delete will fail if the pm is different than the one used to
  // load the object - we must close the object when we're done
  public void deleteRegistration(String regId) {
    if (ctx == null) {
      return;
    }
    PersistenceManager pm = DBHelper.getPMF(ctx).getPersistenceManager();
    try {
      List<DeviceInfo> registrations = DeviceInfo.getDeviceInfoForUserEmail(pm, userEmail);
      for (int i = 0; i < registrations.size(); i++) {
        DeviceInfo deviceInfo = registrations.get(i);
        if (deviceInfo.getDeviceRegistrationID().equals(regId)) {
          pm.deletePersistent(deviceInfo);
          // Keep looping in case of duplicates

          log.log(
              Level.INFO,
              "RequestInfo:deleteRegistration() : deleted deviceInfo for "
                  + deviceInfo.getDeviceRegistrationID());
        }
      }
    } catch (JDOObjectNotFoundException e) {
      log.warning("RequestInfo:deleteRegistration() : User unknown");
    } catch (Exception e) {
      log.warning(
          "RequestInfo:deleteRegistration() : Error unregistering device: " + e.getMessage());
    } finally {
      pm.close();
    }
  }
示例#3
0
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    log.log(Level.INFO, "RegisterServlet.doPOST() : START RegisterServlet.doPOST()");

    resp.setContentType("text/plain");

    GeatteRegisterRequestInfo reqInfo =
        GeatteRegisterRequestInfo.processRequest(req, resp, getServletContext());
    if (reqInfo == null) {
      log.severe("RegisterServlet.doPOST() : can not load RequestInfo!!");
      return;
    }

    // Because the deviceRegistrationId isn't static, we use a static
    // identifier for the device. (Can be null in older clients)
    String deviceId = reqInfo.getParameter(Config.DEVICE_ID_PARAM);

    if (deviceId == null) {
      resp.setStatus(400);
      resp.getWriter().println(ERROR_STATUS + "(Must specify " + Config.DEVICE_ID_PARAM + ")");
      log.severe(
          "RegisterServlet.doPOST() : Missing device id, " + Config.DEVICE_ID_PARAM + " is null");
      return;
    } else {
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : user sent a " + Config.DEVICE_ID_PARAM + " = " + deviceId);
    }

    String phoneNumber = reqInfo.getParameter(Config.DEV_PHONE_NUMBER_PARAM);

    if (phoneNumber == null) {
      resp.setStatus(400);
      resp.getWriter()
          .println(ERROR_STATUS + "(Must specify " + Config.DEV_PHONE_NUMBER_PARAM + ")");
      log.severe(
          "RegisterServlet.doPOST() : Missing phone number, "
              + Config.DEV_PHONE_NUMBER_PARAM
              + " is null");
      return;
    } else {
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : user sent a "
              + Config.DEV_PHONE_NUMBER_PARAM
              + " = "
              + phoneNumber);
    }

    String phoneCountryIso = reqInfo.getParameter(Config.DEV_PHONE_COUNTRY_ISO_PARAM);

    if (phoneCountryIso == null) {
      // default is us
      phoneCountryIso = "us";
      log.severe(
          "RegisterServlet.doPOST() : Missing phone country iso, "
              + Config.DEV_PHONE_COUNTRY_ISO_PARAM
              + " is null");
      return;
    } else {
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : user sent a "
              + Config.DEV_PHONE_COUNTRY_ISO_PARAM
              + " = "
              + phoneCountryIso);
    }

    PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
    PhoneNumber numberProto = null;
    try {
      numberProto = phoneUtil.parse(phoneNumber, phoneCountryIso);
    } catch (NumberParseException npe) {
      log.log(Level.WARNING, "RegisterServlet.doPOST(): NumberParseException was thrown: ", npe);
    }

    if (numberProto != null && phoneUtil.isValidNumber(numberProto)) {
      phoneNumber = phoneUtil.format(numberProto, PhoneNumberFormat.E164);
    } else {
      log.log(
          Level.WARNING,
          "RegisterServlet.doPOST() : Invalid phone number so use passed-in number, "
              + Config.DEV_PHONE_NUMBER_PARAM
              + " = "
              + phoneNumber
              + ", countryIso = "
              + phoneCountryIso);
    }

    if (reqInfo.deviceRegistrationID == null) {
      resp.setStatus(400);
      resp.getWriter().println(ERROR_STATUS + "(Must specify " + Config.DEV_REG_ID_PARAM + ")");
      log.severe(
          "RegisterServlet.doPOST() : Missing registration id, reqInfo.deviceRegistrationID is null");
      return;
    } else {
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : reqInfo.deviceRegistrationID = "
              + reqInfo.deviceRegistrationID);
    }

    String deviceName = reqInfo.getParameter(Config.DEVICE_NAME_PARAM);

    if (deviceName == null) {
      deviceName = "Phone";
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : use default "
              + Config.DEVICE_NAME_PARAM
              + " = "
              + deviceName);
    } else {
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : user sent a "
              + Config.DEVICE_NAME_PARAM
              + " = "
              + deviceName);
    }
    // TODO: generate the device name by adding a number suffix for multiple
    // devices of same type. Change android app to send model/type.

    String deviceType = reqInfo.getParameter(Config.DEVICE_TYPE_PARAM);

    if (deviceType == null) {
      deviceType = DeviceInfo.TYPE_AC2DM;
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : use default "
              + Config.DEVICE_TYPE_PARAM
              + " = "
              + deviceType);
    } else {
      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : user sent a "
              + Config.DEVICE_TYPE_PARAM
              + " = "
              + deviceType);
    }

    // Context-shared PMF.
    PersistenceManager pm = DBHelper.getPMF(getServletContext()).getPersistenceManager();

    try {
      List<DeviceInfo> registrations = reqInfo.devices;

      if (registrations.size() > MAX_DEVICES) {
        log.log(
            Level.INFO,
            "RegisterServlet.doPOST() : user has too many devices, registrations.size = "
                + registrations.size());
        // we could return an error - but user can't handle it yet.
        // we can't let it grow out of bounds.
        // TODO: we should also define a 'ping' message and
        // expire/remove
        // unused registrations
        DeviceInfo oldest = registrations.get(0);
        if (oldest.getRegistrationTimestamp() == null) {
          log.log(
              Level.INFO,
              "RegisterServlet.doPOST() : user has too many devices, trying to remove old one = "
                  + oldest.getDeviceRegistrationID());
          pm.deletePersistent(oldest);
        } else {
          long oldestTime = oldest.getRegistrationTimestamp().getTime();
          for (int i = 1; i < registrations.size(); i++) {
            if (registrations.get(i).getRegistrationTimestamp().getTime() < oldestTime) {
              oldest = registrations.get(i);
              oldestTime = oldest.getRegistrationTimestamp().getTime();
            }
          }
          log.log(
              Level.INFO,
              "RegisterServlet.doPOST() : user has too many devices, trying to remove old one = "
                  + oldest.getDeviceRegistrationID());
          pm.deletePersistent(oldest);
        }
      }

      // Get device if it already exists, else create
      // String suffix = (deviceId != null ? "#" +
      // Long.toHexString(Math.abs(deviceId.hashCode())) : "");
      // Key key = KeyFactory.createKey(DeviceInfo.class.getSimpleName(),
      // reqInfo.userName + suffix);
      Key key = KeyFactory.createKey(DeviceInfo.class.getSimpleName(), deviceId);

      DeviceInfo device = null;
      try {
        device = pm.getObjectById(DeviceInfo.class, key);
      } catch (JDOObjectNotFoundException e) {
      }
      if (device == null) {
        log.log(
            Level.INFO,
            "RegisterServlet.doPOST() : can not find a DeviceInfo by key = "
                + key
                + ", create a new one");

        // clean devices for same phone number, only one device allowed for one phone
        try {
          List<DeviceInfo> devicesForSameNumber =
              DeviceInfo.getDeviceInfoForNumber(pm, phoneNumber, phoneCountryIso);
          for (DeviceInfo deviceSameNumber : devicesForSameNumber) {
            pm.deletePersistent(deviceSameNumber);
          }
        } catch (JDOObjectNotFoundException e) {
        }

        device = new DeviceInfo(key, reqInfo.deviceRegistrationID);
        device.setType(deviceType);
      } else {
        log.log(
            Level.INFO,
            "RegisterServlet.doPOST() : find a DeviceInfo by key = "
                + key
                + ", update deviceRegistrationID to "
                + reqInfo.deviceRegistrationID);

        // update registration id
        device.setDeviceRegistrationID(reqInfo.deviceRegistrationID);
        device.setRegistrationTimestamp(new Date());
      }

      device.setPhoneNumber(phoneNumber); // update phoneNumber
      device.setCountryCode(phoneCountryIso); // update country code
      device.setUserEmail(reqInfo.getUserEmail()); // update user email
      device.setDeviceName(deviceName); // update display name
      // TODO: only need to write if something changed, for chrome nothing
      // changes, we just create a new channel
      pm.makePersistent(device);

      log.log(
          Level.INFO,
          "RegisterServlet.doPOST() : Registered device userEmail = "
              + reqInfo.getUserEmail()
              + ", deviceType = "
              + deviceType
              + ", deviceRegistrationID = "
              + reqInfo.deviceRegistrationID
              + ", key = "
              + key);

      // if type is IOS, register to Urban
      if (device.getType().equalsIgnoreCase(DeviceInfo.TYPE_IOS)) {
        doRegisterIOSToUrban(device);
        resp.getWriter().println(OK_STATUS);
      } else if (device.getType().equalsIgnoreCase(DeviceInfo.TYPE_ANDROID)
          || device.getType().equalsIgnoreCase(DeviceInfo.TYPE_AC2DM)) {
        resp.getWriter().println(OK_STATUS);
      } else {
        resp.getWriter().println(ERROR_STATUS + "(Wrong " + Config.DEVICE_TYPE_PARAM + ")");
      }

      log.log(Level.INFO, "RegisterServlet.doPOST() : END RegisterServlet.doPOST()");
    } catch (Exception e) {
      resp.setStatus(500);
      resp.getWriter().println(ERROR_STATUS + " (Error registering device)");
      log.log(Level.WARNING, "RegisterServlet.doPOST() : Error registering device.", e);
    } finally {
      pm.close();
    }
  }