blob: d31c19d0061b415900b9348ec07a630a424ce7b2 [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.vysper.xmpp.modules.roster;
import static org.apache.vysper.xmpp.modules.roster.AskSubscriptionType.ASK_SUBSCRIBE;
import static org.apache.vysper.xmpp.modules.roster.AskSubscriptionType.ASK_SUBSCRIBED;
import static org.apache.vysper.xmpp.modules.roster.AskSubscriptionType.NOT_SET;
import static org.apache.vysper.xmpp.modules.roster.RosterSubscriptionMutator.Result.ALREADY_SET;
import static org.apache.vysper.xmpp.modules.roster.RosterSubscriptionMutator.Result.FAILED;
import static org.apache.vysper.xmpp.modules.roster.RosterSubscriptionMutator.Result.OK;
import static org.apache.vysper.xmpp.modules.roster.SubscriptionType.BOTH;
import static org.apache.vysper.xmpp.modules.roster.SubscriptionType.FROM;
import static org.apache.vysper.xmpp.modules.roster.SubscriptionType.NONE;
import static org.apache.vysper.xmpp.modules.roster.SubscriptionType.TO;
/**
* changes roster item subscription and ask states according to the protocol's spec
*
* @author The Apache MINA Project (dev@mina.apache.org)
*/
public class RosterSubscriptionMutator {
private static RosterSubscriptionMutator SINGLETON = new RosterSubscriptionMutator();
public static RosterSubscriptionMutator getInstance() {
return SINGLETON;
}
public enum Result {
/** the type was added to the subscription state**/
OK,
/** an illegal type was supplied **/
ILLEGAL_ARGUMENT,
/** the type was already present **/
ALREADY_SET,
/** the type was not added **/
FAILED
}
protected RosterSubscriptionMutator() {
; // empty
}
/**
* adds a subscription request to the roster item
*/
public Result add(RosterItem item, AskSubscriptionType addAskSubscriptionType) {
synchronized (item) {
return addWorker(item, addAskSubscriptionType);
}
}
/**
* adds a subscription to the roster item
*/
public Result add(RosterItem item, SubscriptionType addSubscriptionType) {
synchronized (item) {
return addWorker(item, addSubscriptionType);
}
}
/**
* removes a subscription from the roster item
*/
public Result remove(RosterItem item, SubscriptionType removeSubscriptionType) {
synchronized (item) {
return removeWorker(item, removeSubscriptionType);
}
}
protected Result addWorker(RosterItem item, SubscriptionType addSubscriptionType) {
switch (addSubscriptionType) {
case NONE:
case BOTH:
case REMOVE:
return Result.ILLEGAL_ARGUMENT;
case FROM:
return addFrom(item);
case TO:
return addTo(item);
default:
throw new IllegalArgumentException("unhandled SubscriptionType " + addSubscriptionType.value());
}
}
protected Result addWorker(RosterItem item, AskSubscriptionType addAskSubscriptionType) {
switch (addAskSubscriptionType) {
case NOT_SET:
return Result.ILLEGAL_ARGUMENT;
case ASK_SUBSCRIBE:
return addAskSubscribe(item);
case ASK_SUBSCRIBED:
return addAskSubscribed(item);
default:
throw new IllegalArgumentException("unhandled SubscriptionType " + addAskSubscriptionType.value());
}
}
protected Result addAskSubscribe(RosterItem item) {
SubscriptionType type = item.getSubscriptionType();
AskSubscriptionType typeAsk = item.getAskSubscriptionType();
if (type.includesTo())
return ALREADY_SET;
if (typeAsk == ASK_SUBSCRIBE)
return OK;
// IGNORE this, overwrite! if (typeAsk == ASK_SUBSCRIBED) return ALREADY_SET;
item.setAskSubscriptionType(ASK_SUBSCRIBE);
return OK;
}
protected Result addAskSubscribed(RosterItem item) {
SubscriptionType type = item.getSubscriptionType();
AskSubscriptionType typeAsk = item.getAskSubscriptionType();
if (type.includesFrom())
return ALREADY_SET;
if (typeAsk == ASK_SUBSCRIBE)
return FAILED; // TODO think about return value
if (typeAsk == ASK_SUBSCRIBED)
return OK;
item.setAskSubscriptionType(ASK_SUBSCRIBED);
return OK;
}
protected Result addTo(RosterItem item) {
SubscriptionType type = item.getSubscriptionType();
if (type.includesTo())
return ALREADY_SET;
if (type == NONE) {
type = TO;
} else if (type == FROM) {
type = BOTH;
}
item.setSubscriptionType(type);
if (item.getAskSubscriptionType() == ASK_SUBSCRIBE)
item.setAskSubscriptionType(NOT_SET);
return OK;
}
protected Result addFrom(RosterItem item) {
SubscriptionType type = item.getSubscriptionType();
if (type.includesFrom())
return ALREADY_SET;
if (type == NONE) {
type = FROM;
} else if (type == TO) {
type = BOTH;
}
item.setSubscriptionType(type);
if (item.getAskSubscriptionType() == ASK_SUBSCRIBED)
item.setAskSubscriptionType(NOT_SET);
return OK;
}
protected Result removeWorker(RosterItem item, SubscriptionType removeSubscriptionType) {
switch (removeSubscriptionType) {
case NONE:
case BOTH:
case REMOVE:
return Result.ILLEGAL_ARGUMENT;
case FROM:
return removeFrom(item);
case TO:
return removeTo(item);
default:
throw new IllegalArgumentException("unhandled SubscriptionType " + removeSubscriptionType.value());
}
}
protected Result removeTo(RosterItem item) {
SubscriptionType type = item.getSubscriptionType();
if (!type.includesTo()) {
// if sub was asked, remove that.
AskSubscriptionType askType = item.getAskSubscriptionType();
if (askType != ASK_SUBSCRIBE)
return ALREADY_SET;
item.setAskSubscriptionType(NOT_SET);
return OK;
}
if (type == BOTH) {
type = FROM;
} else if (type == TO) {
type = NONE;
}
item.setSubscriptionType(type);
return OK;
}
protected Result removeFrom(RosterItem item) {
SubscriptionType type = item.getSubscriptionType();
if (!type.includesFrom()) {
// if sub was asked, remove that.
AskSubscriptionType askType = item.getAskSubscriptionType();
if (askType != ASK_SUBSCRIBED)
return ALREADY_SET;
item.setAskSubscriptionType(NOT_SET);
return OK;
}
if (type == BOTH) {
type = TO;
} else if (type == FROM) {
type = NONE;
}
item.setSubscriptionType(type);
return OK;
}
}