Utils.java
/***************************************************************************
* Copyright (C) 2003-2008 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
***************************************************************************/
package org.exoplatform.forum.service;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.jcr.Value;
import org.exoplatform.forum.common.CommonUtils;
import org.exoplatform.forum.common.UserHelper;
import org.exoplatform.forum.common.jcr.KSDataLocation;
import org.exoplatform.forum.service.SortSettings.Direction;
import org.exoplatform.forum.service.SortSettings.SortField;
import org.exoplatform.forum.service.filter.model.CategoryFilter;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.Group;
import org.exoplatform.services.organization.User;
public class Utils implements ForumNodeTypes {
private final static Log LOG = ExoLogger.getLogger(Utils.class);
public final static String TYPE_CATEGORY = "exo:forumCategory".intern();
public final static String TYPE_FORUM = "exo:forum".intern();
public final static String TYPE_TOPIC = "exo:topic".intern();
public final static String USER_PROFILES_TYPE = "exo:forumUserProfile".intern();
public final static String FORUM_SERVICE = "ForumService".intern();
public final static String USER_PROFILES = "UserProfile".intern();
public final static String FORUM_SUBSCRIOTION = "forumSubscription".intern();
public final static String NT_UNSTRUCTURED = "nt:unstructured".intern();
public final static String FORUMADMINISTRATION = "forumAdministration".intern();
public static final String USER_PROFILE_DELETED = "userProfileDeleted".intern();
public final static String CATEGORY = "forumCategory".intern();
public final static String FORUM = "forum".intern();
public final static String TOPIC = "topic".intern();
public final static String POST = "post".intern();
public final static String ATTACHMENT = "attachment";
public final static String POLL = "poll".intern();
public final static String TAG = "tag".intern();
public final static String TOPICTYPE = "topicType".intern();
public final static String PRUNESETTING = "pruneSetting".intern();
public final static String RECEIVE_MESSAGE = "receive".intern();
public final static String SEND_MESSAGE = "send".intern();
public static final String ADMIN = "Administrator".intern();
public static final String MODERATOR = "Moderator".intern();
public static final String USER = "User".intern();
public static final String GUEST = "Guest".intern();
public static final String DELETED = "_deleted".intern();
public static final String CACHE_REPO_NAME = "repositoryName".intern();
public static final String DEFAULT_TENANT_NAME = Long.toHexString(System.currentTimeMillis()
+ System.identityHashCode("currentTenant"));
// Type Modify
public static final int CLOSE = 1;
public static final int LOCK = 2;
public static final int APPROVE = 3;
public static final int STICKY = 4;
public static final int WAITING = 5;
public static final int ACTIVE = 6;
public static final int CHANGE_NAME = 7;
public static final int VOTE_RATING = 8;
public static final int HIDDEN = 9;
public static final String SPACE = " ".intern();
private static Pattern categoryPattern = Pattern.compile("forumCategory([a-zA-Z_0-9])");
private static Pattern forumPattern = Pattern.compile("forum([a-zA-Z_0-9])");
private static Pattern topicPattern = Pattern.compile("topic([a-zA-Z_0-9])");
private static Pattern postPattern = Pattern.compile("post([a-zA-Z_0-9])");
/**
* start with forum prefix.
*/
public static final String FORUM_SPACE_ID_PREFIX = (FORUM + "Space").intern();
public static final String CATEGORY_SPACE = "spaces";
public static final String CATEGORY_SPACE_ID_PREFIX = (CATEGORY + CATEGORY_SPACE).intern();
public static final String ADMIN_ROLE = "ADMIN".intern();
public static final String DEFAULT_EMAIL_CONTENT = "Hi,</br> You receive this email because you registered for eXo Forum and Topic Watching notification." + "<br/>We would like to inform you that there is a new $ADD_TYPE in the $OBJECT_WATCH_TYPE <strong>$OBJECT_NAME</strong> with the following content: "
+ "<div>_______________<br/>$POST_CONTENT<br/>_______________</div><div>At $TIME on $DATE, posted by <strong>$POSTER</strong> .</div><div>Go directly to the post: " + "<a target=\"_blank\" href=\"$VIEWPOST_LINK\">Click here.</a> <br/>Or go to reply to the post: <a target=\"_blank\" href=\"$REPLYPOST_LINK\">Click here." + "</a></div>".intern();
/**
* Clear characters that have a {@literal codepoint < 31} (non printable) from a string
* @param s string input
* @return the string with all character whose {@literal codepoint<31} removed
*/
public static String removeCharterStrange(String s) {
if (s == null || s.length() <= 0)
return "";
int i = 0;
StringBuilder builder = new StringBuilder();
while (i < s.length()) {
if (s.codePointAt(i) > 31) {
builder.append(s.charAt(i));
}
++i;
}
return builder.toString();
}
static public class DatetimeComparatorDESC implements Comparator<Object> {
public int compare(Object o1, Object o2) throws ClassCastException {
Date date1 = ((User) o1).getCreatedDate();
Date date2 = ((User) o2).getCreatedDate();
return date2.compareTo(date1);
}
}
static public class DatetimeComparatorPostDESC implements Comparator<Post> {
public int compare(Post o1, Post o2) throws ClassCastException {
Date date1 = o2.getCreatedDate();
Date date2 = o1.getCreatedDate();
return date2.compareTo(date1);
}
}
static public class CategoryNameComparator implements Comparator<Object> {
public enum DIRECTION {
DESC, ASC
}
private DIRECTION type = DIRECTION.ASC;
public CategoryNameComparator() {
}
public CategoryNameComparator(DIRECTION type) {
this.type = type;
}
public int compare(Object o1, Object o2) throws ClassCastException {
String name1 = "", name2 = "";
if (o1 instanceof CategoryFilter) {
name1 = ((CategoryFilter) o1).getCategoryName().toUpperCase();
name2 = ((CategoryFilter) o2).getCategoryName().toUpperCase();
} else {
name1 = ((Category) o1).getCategoryName().toUpperCase();
name2 = ((Category) o2).getCategoryName().toUpperCase();
}
return (type == DIRECTION.ASC) ? name1.compareTo(name2) : name2.compareTo(name1);
}
}
/**
* Compare two arrays and to verify there is a difference in content between two string arrays. The elements may not appear in the same order in both arrays.
* @param a first string array to compare
* @param b second string array to compare
* @return true if there is a difference in content or size between the two arrays, false otherwise.
*/
public static boolean arraysHaveDifferentContent(String[] a, String[] b) {
if (a.length == b.length) {
List<String> list = Arrays.asList(b);
for (int i = 0; i < a.length; i++) {
if (!list.contains(a[i])) {
return true;
}
}
} else {
return true;
}
return false;
}
/**
* Compare two lists and to verify there is a difference in content between two string lists. The elements may not appear in the same order in both lists.
* @param a first string list to compare
* @param b second string list to compare
* @return true if there is a difference in content or size between the two lists, false otherwise.
* @see #arraysHaveDifferentContent(String[], String[])
*/
public static boolean listsHaveDifferentContent(List<String> a, List<String> b) {
if (a.size() == b.size()) {
for (String s : b) {
if (!a.contains(s)) {
return true;
}
}
} else {
return true;
}
return false;
}
/**
* Converts a map to a string array representation. Each map entry is converted into a string item. String items will be of the form "key,value".
* This is the reverse operation of {@link #arrayToMap(String[])}
* @param map map to convert
* @return converted list of string
*/
public static String[] mapToArray(Map<String, String> map) {
if (map.isEmpty())
return new String[] { " " };
String str = map.toString().replace(" ", "").replace("{", "").replace("}", "");
str = str.replace(",", ";").replace("=", ",");
return str.split(";");
}
/**
* Convert a String array to a map. key and values must be comma separated. For example : "color,blue" will create an entry "blue" with key "color" in the map.
* A string not conforming to the pattern "key,value" is ignored
* @param strs List of string to scan
* @return map representation
*/
public static Map<String, String> arrayToMap(String[] strs) {
Map<String, String> map = new HashMap<String, String>();
String[] arr;
for (int i = 0; i < strs.length; i++) {
arr = strs[i].split(",");
if (arr.length == 2)
map.put(arr[0], arr[1]);
}
return map;
}
/**
* Create a JCR xpath condition that match a property against a list of values with an or condition.
* Note that if the property does not exist, the condition is matched too (means : values are combined with not(property))
* @param property property to match
* @param list list of possible values
* @return the JCR xpath predicate condition to match the property against values.
*/
public static String propertyMatchAny(String property, List<String> list) {
StringBuilder builder = new StringBuilder();
if (!list.isEmpty()) {
int t = 0;
for (String string : list) {
if (t == 0)
builder.append("(not(").append(property).append(") or ").append(property).append("='' or ").append(property).append("='").append(string).append("'");
else
builder.append(" or ").append(property).append("='").append(string).append("'");
t = 1;
}
if (t == 1)
builder.append(")");
}
return builder.toString();
}
/**
* Note that
* @param list
* @param list1
* @return
*/
public static boolean isListContentItemList(List<String> list, List<String> list1) {
if (list1 == null || (list1.size() == 1 && isEmpty(list1.get(0))))
return false;
for (String string : list1) {
if (list.contains(string))
return true;
}
return false;
}
/**
* Transforms a List of strings into a string array and clear any blank entry.
* A blank entry is the 'space' value (aka " ").
* @param list List of Strings to transform
* @return String array cleared of blanks
*/
public static String[] getStringsInList(List<String> list){
if (list.size() > 1) {
while (list.contains(" ")) {
list.remove(" ");
}
}
return list.toArray(new String[list.size()]);
}
/**
* Extract the items two lists have in common.
* @param pList first list
* @param cList second list
* @return a new list containing only the common elements between the two lists in input
* @throws Exception
*/
public static List<String> extractSameItems(List<String> pList, List<String> cList) throws Exception {
List<String> list = new ArrayList<String>();
for (String string : pList) {
if (cList.contains(string))
list.add(string);
}
return list;
}
/**
* Transforms a jcr Value array into a string array .
* Calls {@link Value#getString()} on each item.
* @see javax.jcr.Value
* @param Val array of values to transform
* @return string array for the Value array
* @throws Exception
*/
public static String[] valuesToArray(Value[] Val) throws Exception {
if (Val.length < 1)
return new String[] {};
List<String> list = new ArrayList<String>();
String s;
for (int i = 0; i < Val.length; ++i) {
s = Val[i].getString();
if (!isEmpty(s))
list.add(s);
}
return list.toArray(new String[list.size()]);
}
/**
* Transforms a jcr Value array into a string list .
* Calls {@link Value#getString()} on each item.
* @see javax.jcr.Value
* @param values array of values to transform
* @return string list for the Value array
* @throws Exception
*/
public static List<String> valuesToList(Value[] values) throws Exception {
List<String> list = new ArrayList<String>();
if (values.length < 1)
return list;
String s;
for (int i = 0; i < values.length; ++i) {
s = values[i].getString();
if (!isEmpty(s))
list.add(s);
}
return list;
}
@SuppressWarnings("unchecked")
public static <T> T[] arrayCopy(final T[] source) {
// null in, null out
if (source == null) {
return null;
}
// empty in, empty out
if (source.length == 0) {
try {
return (T[]) Array.newInstance(source.getClass().getComponentType(), 0);
} catch (Exception e) {
return null;
// should never occur;
}
}
// instanciate a new array based on first item
T[] dest = (T[]) Array.newInstance(source[0].getClass(), source.length);
System.arraycopy(source, 0, dest, 0, source.length);
return dest;
}
/**
* Check string is null or empty
* @param s
* @return boolean
*/
public static boolean isEmpty(String s) {
return (s == null || s.trim().length() <= 0) ? true : false;
}
/**
* check string array is whether empty or not
* @param array
* @return false if at least one element of array is not empty, true in the opposite case.
*/
public static boolean isEmpty(String[] array) {
if (array != null && array.length > 0) {
for (String s : array) {
if (s != null && s.trim().length() > 0)
return false;
}
}
return true;
}
/**
* get Xpath query by one property.
* @param typeAdd
* @param property
* @param value
* @return String
*/
@Deprecated
public static String getQueryByProperty(String typeAdd, String property, String value) {
StringBuilder strBuilder = new StringBuilder();
if (!isEmpty(value) && !isEmpty(property)) {
if (!isEmpty(typeAdd)) {
strBuilder.append(SPACE).append(typeAdd).append(SPACE);
}
strBuilder.append("(@").append(property).append("='").append(value).append("')");
}
return strBuilder.toString();
}
public static String getSQLQueryByProperty(String typeAdd, String property, String value) {
StringBuilder strBuilder = new StringBuilder();
if (!isEmpty(value) && !isEmpty(property)) {
if (!isEmpty(typeAdd)) {
strBuilder.append(SPACE).append(typeAdd).append(SPACE);
}
strBuilder.append("(").append(property).append("='").append(value).append("')");
}
return strBuilder.toString();
}
/**
* get Xpath query when get list post.
* @param isApproved
* @param isHidden
* @param isWaiting
* @param userLogin
* @return StringBuilder
*/
@Deprecated
public static StringBuilder getPathQuery(String isApproved, String isHidden, String isWaiting, String userLogin) throws Exception {
StringBuilder strBuilder = new StringBuilder();
String typeAdd = null;
String str = getQueryByProperty(typeAdd, EXO_USER_PRIVATE, userLogin);
if (!isEmpty(str)) {
strBuilder.append("(").append(str);
typeAdd = "or";
}
if ("or".equals(typeAdd)) {
strBuilder.append(getQueryByProperty(typeAdd, EXO_USER_PRIVATE, EXO_USER_PRI)).append(")");
typeAdd = "and";
}
str = getQueryByProperty(typeAdd, EXO_IS_APPROVED, isApproved);
if (!isEmpty(str)) {
strBuilder.append(str);
typeAdd = "and";
}
str = getQueryByProperty(typeAdd, EXO_IS_HIDDEN, isHidden);
if (!isEmpty(str)) {
strBuilder.append(str);
typeAdd = "and";
}
str = getQueryByProperty(typeAdd, EXO_IS_WAITING, isWaiting);
if (!isEmpty(str)) {
strBuilder.append(str);
}
if (strBuilder.length() > 0) {
return new StringBuilder("[").append(strBuilder).append("]");
}
return new StringBuilder();
}
public static StringBuilder getSQLQuery(String isApproved, String isHidden, String isWaiting, String userLogin) throws Exception {
StringBuilder sqlQuery = new StringBuilder();
String typeAdd = null;
String str = getSQLQueryByProperty(typeAdd, EXO_USER_PRIVATE, userLogin);
if (!isEmpty(str)) {
sqlQuery.append("(").append(str);
typeAdd = "OR";
}
if ("OR".equals(typeAdd)) {
sqlQuery.append(getSQLQueryByProperty(typeAdd, EXO_USER_PRIVATE, EXO_USER_PRI)).append(")");
typeAdd = "AND";
}
str = getSQLQueryByProperty(typeAdd, EXO_IS_APPROVED, isApproved);
if (!isEmpty(str)) {
sqlQuery.append(str);
typeAdd = "AND";
}
str = getSQLQueryByProperty(typeAdd, EXO_IS_HIDDEN, isHidden);
if (!isEmpty(str)) {
sqlQuery.append(str);
typeAdd = "AND";
}
str = getSQLQueryByProperty(typeAdd, EXO_IS_WAITING, isWaiting);
if (!isEmpty(str)) {
sqlQuery.append(str);
}
return sqlQuery;
}
/**
* Build Xpath query for check has property existing.
* @param property is the property of node
* @return String
* @since 2.2.10
*/
@Deprecated
public static String buildXpathHasProperty(String property) {
StringBuilder builder = new StringBuilder();
if (!isEmpty(property)) {
builder.append("(not(@").append(property).append(") or @")
.append(property).append("='' or @")
.append(property).append("=' ')");
}
return builder.toString();
}
public static String buildSQLHasProperty(String property) {
StringBuilder builder = new StringBuilder();
if (!isEmpty(property)) {
builder.append(property).append("='' OR ")
.append(property).append("=' ' OR ")
.append(property).append(" IS NULL");
}
return builder.toString();
}
public static String buildSQLHasNotProperty(String property) {
StringBuilder builder = new StringBuilder();
if (!isEmpty(property)) {
builder.append(property).append("<>'' AND ")
.append(property).append("<>' ' AND ")
.append(property).append(" IS NOT NULL");
}
return builder.toString();
}
/**
* Build Xpath query for case comparator with all properties of user and other property.
* @param property is the property of node
* @param groupAndMembershipInfos is list all properties of user
* @return String
* @since 2.2.10
*/
@Deprecated
public static String buildXpathByUserInfo(String property, List<String> groupAndMembershipInfos) {
StringBuilder query = new StringBuilder();
for (String str : groupAndMembershipInfos) {
if (query.length() > 0) {
query.append(" or ");
}
query.append("@").append(property).append(" = '").append(str).append("'");
if (ForumServiceUtils.isGroupExpression(str)) {
query.append(" or @").append(property).append(" = '*:").append(str).append("'");
} else if (ForumServiceUtils.isMembershipExpression(str)) {
str = str.substring(str.indexOf(":") + 1);
query.append(" or @").append(property).append(" = '*:").append(str).append("'");
}
}
return query.toString();
}
public static String buildSQLByUserInfo(String property, List<String> groupAndMembershipInfos) {
StringBuilder query = new StringBuilder();
for (String str : groupAndMembershipInfos) {
if (query.length() > 0) {
query.append(" OR ");
}
query.append(property).append("='").append(str).append("'");
if (ForumServiceUtils.isGroupExpression(str)) {
query.append(" OR ").append(property).append("='*:").append(str).append("'");
} else if (ForumServiceUtils.isMembershipExpression(str)) {
str = str.substring(str.indexOf(":") + 1);
query.append(" OR ").append(property).append("='*:").append(str).append("'");
}
}
return query.toString();
}
@Deprecated
public static String buildTopicQuery(SortSettings sortSettings, String strQuery, String strOrderBy, String forumPath) throws Exception {
SortField orderBy = sortSettings.getField();
Direction orderType = sortSettings.getDirection();
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(JCR_ROOT).append(forumPath).append("/element(*,").append(EXO_TOPIC).append(")");
if (strQuery != null && strQuery.length() > 0) {
// @exo:isClosed,
// @exo:isWaiting ,
// @exo:isApprove
// @exo:isActive
stringBuffer.append("[").append(strQuery).append("]");
}
stringBuffer.append(" order by @").append(EXO_IS_STICKY).append(DESCENDING);
if (strOrderBy == null || Utils.isEmpty(strOrderBy)) {
if (orderBy != null) {
stringBuffer.append(", @exo:").append(orderBy.toString()).append(" ").append(orderType);
if (!orderBy.equals(SortField.LASTPOST)) {
stringBuffer.append(", @").append(EXO_LAST_POST_DATE).append(DESCENDING);
}
} else {
stringBuffer.append(", @").append(EXO_LAST_POST_DATE).append(DESCENDING);
}
} else {
stringBuffer.append(", @exo:").append(strOrderBy);
if (strOrderBy.indexOf(SortField.LASTPOST.toString()) < 0) {
stringBuffer.append(", @").append(EXO_LAST_POST_DATE).append(DESCENDING);
}
}
String pathQuery = stringBuffer.toString();
return pathQuery;
}
/**
* @param userId
* @return
*/
public static List<String> getGroupSpaceOfUser(String userId) {
List<String> groupId = new ArrayList<String>();
try {
Collection<Group> groups = UserHelper.getGroupHandler().findGroupsOfUser(userId);
for (Group group : groups) {
if (group.getId().indexOf(CommonUtils.SLASH + CATEGORY_SPACE) >= 0) {
groupId.add(group.getGroupName());
}
}
} catch (Exception e) {
LOG.warn("The method findGroupsOfUser() cannot access the database.");
}
return groupId;
}
/**
* Build Xpath query to get all forums in spaces of user.
* @param userId
* @return String
*
* @deprecated
*/
public static String buildQueryForumInSpaceOfUser(String userId, List<String> groupIds) {
if (isEmpty(userId) == false) {
if (groupIds.size() > 0) {
StringBuilder queryForum = new StringBuilder("(");
for (String groupId : groupIds) {
if (queryForum.length() > 10) {
queryForum.append(" or ");
}
queryForum.append("(@").append(Utils.EXO_ID).append("='").append(Utils.FORUM_SPACE_ID_PREFIX).append(groupId).append("')");
}
queryForum.append(")");
return queryForum.toString();
}
}
return CommonUtils.EMPTY_STR;
}
public static String buildSQLQueryForumInSpaceOfUser(String userId) {
List<String> groupIds = getGroupSpaceOfUser(userId);
if (groupIds.size() > 0) {
StringBuilder queryForum = new StringBuilder("(");
for (String groupId : groupIds) {
if (queryForum.length() > 10) {
queryForum.append(" OR ");
}
queryForum.append("(").append(Utils.EXO_ID).append("='").append(Utils.FORUM_SPACE_ID_PREFIX).append(groupId).append("')");
}
queryForum.append(")");
return queryForum.toString();
}
return CommonUtils.EMPTY_STR;
}
/**
* Checking a user who whether contained Users/MemberShip/Group ?
* @param listOfCanviewrs
* @param listOfBoundUsers
* @return boolean
*/
static public boolean hasPermission(List<String> listOfCanviewrs, List<String> listOfBoundUsers) {
if (listOfBoundUsers == null || listOfCanviewrs == null) {
return false;
}
List<String> groups = new ArrayList<String>();
List<String> groupsAllmembershipType = new ArrayList<String>();
for (String str : listOfBoundUsers) {
if (str.indexOf("/") >= 0) {
groups.add(str.substring(str.indexOf("/")));
}
if (str.indexOf("*") >= 0) {// user has membershipType *
str = str.substring(str.indexOf("/"));
groupsAllmembershipType.add(str);
}
if (listOfCanviewrs.contains(str)) {
return true;
}
}
if (groups.size() > 0 || groupsAllmembershipType.size() > 0) {
for (String str : listOfCanviewrs) {
if (str.indexOf("*") >= 0) {// listPlugin has membershipType *
str = str.substring(str.indexOf("/"));
if (groups.contains(str)) {
return true;
}
}
if (str.indexOf(":") > 0) {
str = str.substring(str.indexOf("/"));
}
if (groupsAllmembershipType.contains(str)) {
return true;
}
}
}
return false;
}
/**
* Get current tenant name via repository name
* @return
* @since 2.2.9
* @deprecated will remove on version 4.1-RC2
*/
static public String getCurrentTenantName() {
return DEFAULT_TENANT_NAME;
}
/**
* @param onlineUserMap
* @return
* @since 2.2.9
* @deprecated will remove on version 4.1-RC2
*/
static public List<String> getOnlineUserByTenantName(Map<String, List<String>> onlineUserMap) {
return new ArrayList<String>();
}
/**
* Get Category ID from path.
* @param path
* @return
* @since 2.3.0
*/
public static String getCategoryId(String path) {
return getIdByType(path, CATEGORY);
}
/**
* Get Category path.
* @param path
* @return
* @since 2.3.0
*/
public static String getCategoryPath(String path) {
return getPathByType(path, CATEGORY);
}
/**
* Get Forum ID from path.
* @param path
* @return
* @since 2.3.0
*/
public static String getForumId(String path) {
if (!Utils.isEmpty(path) && path.lastIndexOf(Utils.FORUM) != -1) {
String categoryId = getCategoryId(path);
if (!isEmpty(categoryId)) {
path = path.substring(path.lastIndexOf(categoryId) + categoryId.length());
return getForumId(path);
}
}
return getIdByType(path, FORUM);
}
/**
* Get Forum path.
* @param path
* @return
* @since 2.3.0
*/
public static String getForumPath(String path) {
return getPathByType(path, FORUM);
}
/**
* Get Topic ID from post path.
* @param path
* @return
* @since 4.0
*/
public static String getTopicId(String path) {
return getIdByType(path, TOPIC);
}
/**
* Get Topic path.
* @param path
* @return
* @since 4.0
*/
public static String getTopicPath(String path) {
return getPathByType(path, TOPIC);
}
/**
* Get object path by path and type
*
* @param path
* @param type
* @return
* @since 4.1
*/
public static String getPathByType(String path, String type) {
if (!isEmpty(path) && path.indexOf(type) != -1) {
String objectId = getIdByType(path, type);
return path.substring(0, path.lastIndexOf(objectId) + objectId.length());
}
return null;
}
/**
* Get Post ID from post path.
* @param path
* @return
* @since 4.1-RC2
*/
public static String getPostId(String path) {
if (isEmpty(path) == false && path.lastIndexOf(POST) != -1) {
String postId = path.substring(path.lastIndexOf(POST));
if (postId.indexOf("/") != -1) {
postId = postId.substring(0, postId.indexOf("/"));
}
return postId;
}
return null;
}
/**
* Get object id by path and type
* @param path
* @param type
* @return
* @since 4.1
*/
public static String getIdByType(String path, String type) {
if (isEmpty(path) == false && path.indexOf(type) != -1) {
if (path.indexOf("/") >= 0) {
String[] objectIds = path.split("/");
for (int i = objectIds.length - 1; i >= 0; i--) {
if (objectIds[i].indexOf(type) == 0) {
return objectIds[i];
}
}
} else if (path.indexOf(type) == 0) {
return path;
}
}
return null;
}
/**
* Get sub path.
* @param path
* @return
* @since 4.1
*/
public static String getSubPath(String path) {
String forumHome = KSDataLocation.Locations.FORUM_CATEGORIES_HOME;
if (isEmpty(path) == false && path.indexOf(forumHome) >= 0) {
int index = path.indexOf(forumHome) + forumHome.length() + 1;
return path.substring(index);
}
return path;
}
/**
* Get type of object (category/forum/topic/post) by path.
* @param objectIdOrPath
* @return
* @since 4.1
*/
public static String getObjectType(String objectIdOrPath) {
if (isEmpty(objectIdOrPath)) {
return objectIdOrPath;
}
if (objectIdOrPath.indexOf("/") >= 0) {
String[] objectIds = getSubPath(objectIdOrPath).split("/");
for (int i = objectIds.length - 1; i >= 0; i--) {
String result = isMatcherId(objectIds[i]);
if (!result.equals(objectIds[i])) {
return result;
}
}
return objectIdOrPath;
}
return isMatcherId(objectIdOrPath);
}
private static boolean isMatcher(Pattern pattern, String input) {
Matcher m = pattern.matcher(input);
return m.find() && m.start() == 0;
}
/**
* Matcher the object type by id
* + If objectId is Category's id return type: forumCategory
* + If objectId is forum's id return type: forum
* + If objectId is topic's id return type: topic
* + If objectId is post's id return type: post
* + Other return objectId input
*
* @param objectId
* @return
*/
public static String isMatcherId(String objectId) {
if (isMatcher(postPattern, objectId)) {
return POST;
}
if (isMatcher(topicPattern, objectId)) {
return TOPIC;
}
if (isMatcher(categoryPattern, objectId)) {
return CATEGORY;
}
if (isMatcher(forumPattern, objectId)) {
return FORUM;
}
return objectId;
}
}