package com.ibm.sbt.services.client.connections.communities;
import static com.ibm.sbt.services.client.base.ConnectionsConstants.nameSpaceCtx;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import org.w3c.dom.Node;
import com.ibm.commons.util.StringUtil;
import com.ibm.commons.xml.xpath.XPathExpression;
import com.ibm.sbt.services.client.ClientServicesException;
import com.ibm.sbt.services.client.Response;
import com.ibm.sbt.services.client.base.AtomFeedHandler;
import com.ibm.sbt.services.client.base.BaseService;
import com.ibm.sbt.services.client.base.IFeedHandler;
import com.ibm.sbt.services.client.base.datahandlers.EntityList;
import com.ibm.sbt.services.client.base.util.EntityUtil;
import com.ibm.sbt.services.client.connections.communities.model.CommunityXPath;
import com.ibm.sbt.services.client.connections.communities.util.Messages;
/**
* This class implements additional services to manage widgets inside a Connections Community.
* This code should become part of CommunityService, like management services for Bookmarks, Subcommunities etc.
* The Community Widget itself is modeled by Widget, WidgetXPath etc.
*
* @author Christian Gosch, inovex GmbH, based on code my Carlos Manias
*/
@SuppressWarnings("serial")
public class WidgetCommunityService extends CommunityService {
private static final String COMMUNITY_UNIQUE_IDENTIFIER = "communityUuid";
public static final String COMMUNITYTYPE_PUBLIC = "public";
public static final String COMMUNITYTYPE_RESTRICTED = "publicInviteOnly";
public static final String COMMUNITYTYPE_PRIVATE = "private";
public static final String WidgetsException = "Problem occurred while fetching Widgets of Community with id : {0}";
public static final String WidgetDefIdException = "Missing Widget type definition";
public static final String WIDGET_DEF_ID = "widgetDefId";
/**
* Wrapper method to get a "Widget enabled" Community
* <p>
* fetches community content from server and populates the data member of {@link Community} with the fetched content
* @see CommunityService#getCommunity(String)
*
* @param communityUuid
* id of community
* @return A Community
* @throws ClientServicesException
*/
@Override
public WidgetCommunity getCommunity(String communityUuid) throws ClientServicesException {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(COMMUNITY_UNIQUE_IDENTIFIER, communityUuid);
String url = CommunityUrls.COMMUNITY_INSTANCE.format(this, CommunityUrls.getCommunityUuid(communityUuid));
WidgetCommunity widgetCommunity;
try {
widgetCommunity = (WidgetCommunity)getEntity(url, parameters, getWidgetCommunityFeedHandler());
} catch (ClientServicesException e) {
throw new ClientServicesException(e, Messages.CommunityException, communityUuid);
} catch (Exception e) {
throw new ClientServicesException(e, Messages.CommunityException, communityUuid);
}
return widgetCommunity;
}
/**
* Create sub community for given parent community.
* <br><b>ATTN:</>Sub communities are not allowed to have sub communities themselves!
* @param parentCommunity
* @param title
* @param tags
* @param content
* @param type
* @return {WidgetCommunity}
*/
public WidgetCommunity createSubCommunity(Community parentCommunity, String title, Collection<String> tags, String content, String type) throws ClientServicesException {
WidgetCommunity subCommunity = null;
// set up new community object
Community community = prepareCommunityEntity(title, tags, content, type, null, null);
// create sub community
String uuid = super.createSubCommunity(community, parentCommunity);
// load community object immediately after creation to reflect automatic extensions
subCommunity = this.getCommunity(uuid);
return subCommunity;
}
private Community prepareCommunityEntity(String title, Collection<String> tags, String content, String type, String uuid, Community parentCommunity) {
// set up new community object
Community community = new Community();
if (null != uuid) {
// for update only: "id" is required!
community.setCommunityUuid(uuid);
community.setAsString(CommunityXPath.communityUuid, uuid);
community.setAsString(CommunityXPath.id, uuid);
}
if (null != parentCommunity && null != parentCommunity.getCommunityUuid()) {
community.setParentCommunityUrl(parentCommunity.getSelfUrl());
}
community.setTitle(title); // required
// prepare tags
HashSet<String> interim = new HashSet<String>();
for (Iterator<String> iterator = tags.iterator(); iterator.hasNext();) {
String tag = (String) iterator.next();
interim.add(tag.toLowerCase());
}
tags = interim;
community.setTags(new ArrayList<String>(tags));
community.setContent(content);
// set type:
// - public (view:all, edit:all, membership:self/invite)
// - private (view:members, edit:members, membership:invite)
// - publicInviteOnly (view:all, edit:?, membership:invite)
if (COMMUNITYTYPE_PUBLIC.equals(type) || COMMUNITYTYPE_PRIVATE.equals(type) || COMMUNITYTYPE_RESTRICTED.equals(type)) {
community.setCommunityType(type);
} else {
community.setCommunityType(COMMUNITYTYPE_PUBLIC);
}
return community;
}
/** Create widget of given type at given community
* @param community (required)
* @param widgetDefId (required)
* @return Widget created
*/
public Widget createCommunityWidget(Community community, WidgetDefId widgetDefId) throws ClientServicesException {
if (null == community) {
throw new ClientServicesException(null, Messages.NullCommunityIdException);
}
if (null == widgetDefId) {
throw new ClientServicesException(null, WidgetDefIdException);
}
Widget communityWidget = null;
Widget widget = new Widget();
widget.setWidgetDefId(widgetDefId.toString());
widget.setWidgetLocation("col2"); // required unless hidden is not true
widget.setWidgetHidden(Boolean.FALSE); // optional, default: false
Object widgetPayload = widget.constructCreateRequestBody();
Map<String, String> params = new HashMap<String, String>();
params.put(COMMUNITY_UNIQUE_IDENTIFIER, community.getCommunityUuid()); // CommunityService.COMMUNITY_UNIQUE_IDENTIFIER
Map<String, String> requestheaders = new HashMap<String, String>();
requestheaders.put("Content-Type", "application/atom+xml");
StringBuilder comBaseUrl = new StringBuilder(WidgetCommunityUrls.COMMUNITY_WIDGETS_FEED.format(this)); // "{communities}/service/atom/{authType}/community/widgets"
// Add required parameters
if (null != params && params.size() > 0) {
comBaseUrl.append('?');
boolean setSeparator = false;
for (Map.Entry<String, String> param : params.entrySet()) {
String key = param.getKey();
if (StringUtil.isEmpty(key)) continue;
String value = EntityUtil.encodeURLParam(param.getValue());
if (StringUtil.isEmpty(value)) continue;
if (setSeparator) {
comBaseUrl.append('&');
} else {
setSeparator = true;
}
comBaseUrl.append(key).append('=').append(value);
}
}
String widgetPostUrl = comBaseUrl.toString();
// execute request
Response result = createData(widgetPostUrl, null, requestheaders, widgetPayload);
// read response data
IFeedHandler<Widget> feedHandler = getWidgetFeedHandler();
widget = feedHandler.createEntity(result);
EntityList<Widget> widgetList = getCommunityWidgets(community.getCommunityUuid(), widgetDefId);
if (null != widgetList && widgetList.size() > 0) {
communityWidget = widgetList.get(0);
// TODO Check if an EntityList<Widget> entry is complete (or if fields are missing). CommunityList does NOT contain all entry data!
}
return communityWidget;
}
/**
* Wrapper method to get Widgets of a community
*
* @param communityUuid
* community Id of which Widgets are to be fetched
* @return A list of widgets
* @throws ClientServicesException
*/
public EntityList<Widget> getCommunityWidgets(String communityUuid) throws ClientServicesException {
return getCommunityWidgets(communityUuid, null, null);
}
/**
* Wrapper method to get Widgets of a community
*
* @param communityUuid
* community Id of which Widgets are to be fetched
* @param widgetDefId
* @return A list of widgets
* @throws ClientServicesException
*/
public EntityList<Widget> getCommunityWidgets(String communityUuid, WidgetDefId widgetDefId) throws ClientServicesException {
return getCommunityWidgets(communityUuid, widgetDefId, null);
}
/**
* Wrapper method to get Widgets of a community
*
* @param communityUuid
* community Id of which Widgets are to be fetched
* @param parameters
* @return A list of widgets
* @throws ClientServicesException
*/
public EntityList<Widget> getCommunityWidgets(String communityUuid, Map<String, String> parameters) throws ClientServicesException {
return getCommunityWidgets(communityUuid, null, parameters);
}
/**
* Wrapper method to get Widgets of a community
*
* @param communityUuid
* community Id of which Widgets are to be fetched
* @param widgetDefId
* @param parameters
* @return A list of widgets
* @throws ClientServicesException
*/
public EntityList<Widget> getCommunityWidgets(String communityUuid, WidgetDefId widgetDefId, Map<String, String> parameters) throws ClientServicesException {
if (StringUtil.isEmpty(communityUuid)){
throw new ClientServicesException(null, Messages.NullCommunityIdException);
}
if(null == parameters){
parameters = new HashMap<String, String>();
}
parameters.put(COMMUNITY_UNIQUE_IDENTIFIER, communityUuid);
if (null != widgetDefId) {
parameters.put(WIDGET_DEF_ID, widgetDefId.toString());
}
String requestUrl = WidgetCommunityUrls.COMMUNITY_WIDGETS_FEED.format(this);
EntityList<Widget> widgets = null;
try {
widgets = (EntityList<Widget>) getEntities(requestUrl, parameters, getWidgetFeedHandler());
} catch (ClientServicesException e) {
throw new ClientServicesException(e, WidgetsException, communityUuid);
}
return widgets;
}
public EntityList<Invite> getInvitesList(String requestUrl, Map<String, String> parameters) throws ClientServicesException {
return super.getInviteEntityList(requestUrl, parameters);
}
/***************************************************************
* FeedHandlers for each entity type
****************************************************************/
/**
* Factory method to instantiate a FeedHandler for WidgetCommunities
* @return IFeedHandler<WidgetCommunity>
*/
protected IFeedHandler<WidgetCommunity> getWidgetCommunityFeedHandler() {
return new AtomFeedHandler<WidgetCommunity>(this, false) {
@Override
protected WidgetCommunity entityInstance(BaseService service, Node node, XPathExpression xpath) {
return new WidgetCommunity(service, node, nameSpaceCtx, xpath);
}
};
}
/**
* Factory method to instantiate a FeedHandler for Widgets
* @return IFeedHandler<Widget>
*/
protected IFeedHandler<Widget> getWidgetFeedHandler() {
return new AtomFeedHandler<Widget>(this, false) {
@Override
protected Widget entityInstance(BaseService service, Node node, XPathExpression xpath) {
return new Widget(service, node, nameSpaceCtx, xpath);
}
};
}
}