/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.push.notifications.sender.apple.internal;
import com.liferay.portal.configuration.metatype.bnd.util.ConfigurableUtil;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.util.StreamUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.push.notifications.constants.PushNotificationsConstants;
import com.liferay.push.notifications.exception.PushNotificationsException;
import com.liferay.push.notifications.sender.PushNotificationsSender;
import com.liferay.push.notifications.sender.apple.internal.configuration.ApplePushNotificationsSenderConfiguration;
import com.notnoop.apns.APNS;
import com.notnoop.apns.ApnsService;
import com.notnoop.apns.ApnsServiceBuilder;
import com.notnoop.apns.PayloadBuilder;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
/**
* @author Silvio Santos
* @author Bruno Farache
*/
@Component(
configurationPid = "com.liferay.push.notifications.sender.apple.internal.configuration.ApplePushNotificationsSenderConfiguration",
immediate = true,
property = {"platform=" + ApplePushNotificationsSender.PLATFORM}
)
public class ApplePushNotificationsSender implements PushNotificationsSender {
public static final String PLATFORM = "apple";
@Override
public void send(List<String> tokens, JSONObject payloadJSONObject)
throws Exception {
if (_apnsService == null) {
throw new PushNotificationsException(
"Apple push notifications sender is not configured properly");
}
String payload = buildPayload(payloadJSONObject);
_apnsService.push(tokens, payload);
}
@Activate
@Modified
protected void activate(Map<String, Object> properties) {
ApplePushNotificationsSenderConfiguration
applePushNotificationsSenderConfiguration =
ConfigurableUtil.createConfigurable(
ApplePushNotificationsSenderConfiguration.class,
properties);
String certificatePath =
applePushNotificationsSenderConfiguration.certificatePath();
String certificatePassword =
applePushNotificationsSenderConfiguration.certificatePassword();
if (Validator.isNull(certificatePath) ||
Validator.isNull(certificatePassword)) {
_apnsService = null;
return;
}
ApnsServiceBuilder appleServiceBuilder = APNS.newService();
InputStream inputStream = null;
try {
try {
inputStream = new FileInputStream(certificatePath);
}
catch (FileNotFoundException fnfe) {
ClassLoader classLoader =
ApplePushNotificationsSender.class.getClassLoader();
inputStream = classLoader.getResourceAsStream(certificatePath);
}
if (inputStream == null) {
throw new IllegalArgumentException(
"Unable to find Apple certificate at " + certificatePath);
}
appleServiceBuilder.withCert(inputStream, certificatePassword);
}
finally {
StreamUtil.cleanUp(inputStream);
}
appleServiceBuilder.withDelegate(new AppleDelegate());
if (applePushNotificationsSenderConfiguration.sandbox()) {
appleServiceBuilder.withSandboxDestination();
}
else {
appleServiceBuilder.withProductionDestination();
}
_apnsService = appleServiceBuilder.build();
}
protected String buildPayload(JSONObject payloadJSONObject) {
PayloadBuilder builder = PayloadBuilder.newPayload();
if (payloadJSONObject.has(PushNotificationsConstants.KEY_BADGE)) {
builder.badge(
payloadJSONObject.getInt(PushNotificationsConstants.KEY_BADGE));
}
String body = payloadJSONObject.getString(
PushNotificationsConstants.KEY_BODY);
if (Validator.isNotNull(body)) {
builder.alertBody(body);
}
String bodyLocalizedKey = payloadJSONObject.getString(
PushNotificationsConstants.KEY_BODY_LOCALIZED);
if (Validator.isNotNull(bodyLocalizedKey)) {
builder.localizedKey(bodyLocalizedKey);
}
JSONArray bodyLocalizedArgumentsJSONArray =
payloadJSONObject.getJSONArray(
PushNotificationsConstants.KEY_BODY_LOCALIZED_ARGUMENTS);
if (bodyLocalizedArgumentsJSONArray != null) {
List<String> localizedArguments = new ArrayList<>();
for (int i = 0; i < bodyLocalizedArgumentsJSONArray.length(); i++) {
localizedArguments.add(
bodyLocalizedArgumentsJSONArray.getString(i));
}
builder.localizedArguments(localizedArguments);
}
boolean silent = payloadJSONObject.getBoolean(
PushNotificationsConstants.KEY_SILENT);
if (silent) {
builder.instantDeliveryOrSilentNotification();
}
String sound = payloadJSONObject.getString(
PushNotificationsConstants.KEY_SOUND);
if (Validator.isNotNull(sound)) {
builder.sound(sound);
}
payloadJSONObject.remove(PushNotificationsConstants.KEY_BADGE);
payloadJSONObject.remove(PushNotificationsConstants.KEY_BODY);
payloadJSONObject.remove(PushNotificationsConstants.KEY_BODY_LOCALIZED);
payloadJSONObject.remove(
PushNotificationsConstants.KEY_BODY_LOCALIZED_ARGUMENTS);
payloadJSONObject.remove(PushNotificationsConstants.KEY_SILENT);
payloadJSONObject.remove(PushNotificationsConstants.KEY_SOUND);
builder.customField(
PushNotificationsConstants.KEY_PAYLOAD,
payloadJSONObject.toString());
return builder.build();
}
@Deactivate
protected void deactivate() {
_apnsService = null;
}
private volatile ApnsService _apnsService;
}