edu.internet2.middleware.grouper.ui.util.GrouperUiUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grouper-ui Show documentation
Show all versions of grouper-ui Show documentation
Internet2 Groups Management User Interface
/*******************************************************************************
* Copyright 2012 Internet2
*
* Licensed 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 edu.internet2.middleware.grouper.ui.util;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.jstl.fmt.LocalizationContext;
import edu.internet2.middleware.grouperClient.collections.MultiKey;
import org.apache.commons.collections.set.ListOrderedSet;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.fasterxml.jackson.databind.node.ArrayNode;
import edu.internet2.middleware.grouper.Group;
import edu.internet2.middleware.grouper.GroupFinder;
import edu.internet2.middleware.grouper.GrouperSession;
import edu.internet2.middleware.grouper.Member;
import edu.internet2.middleware.grouper.Stem;
import edu.internet2.middleware.grouper.StemFinder;
import edu.internet2.middleware.grouper.SubjectFinder;
import edu.internet2.middleware.grouper.exception.StemNotFoundException;
import edu.internet2.middleware.grouper.misc.GrouperObject;
import edu.internet2.middleware.grouper.cache.GrouperCache;
import edu.internet2.middleware.grouper.cfg.GrouperConfig;
import edu.internet2.middleware.grouper.exception.GrouperSessionException;
import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiResponseJs;
import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction;
import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction.GuiMessageType;
import edu.internet2.middleware.grouper.grouperUi.beans.ui.TextContainer;
import edu.internet2.middleware.grouper.hibernate.ByHqlStatic;
import edu.internet2.middleware.grouper.hibernate.HibernateSession;
import edu.internet2.middleware.grouper.hooks.logic.HookVeto;
import edu.internet2.middleware.grouper.internal.dao.QueryPaging;
import edu.internet2.middleware.grouper.j2ee.GenericServletResponseWrapper;
import edu.internet2.middleware.grouper.misc.GrouperSessionHandler;
import edu.internet2.middleware.grouper.misc.GrouperStartup;
import edu.internet2.middleware.grouper.privs.AccessPrivilege;
import edu.internet2.middleware.grouper.privs.PrivilegeHelper;
import edu.internet2.middleware.grouper.subj.SubjectHelper;
import edu.internet2.middleware.grouper.ui.GrouperUiFilter;
import edu.internet2.middleware.grouper.util.GrouperUtil;
import edu.internet2.middleware.subject.SourceUnavailableException;
import edu.internet2.middleware.subject.Subject;
import edu.internet2.middleware.subject.SubjectNotFoundException;
import edu.internet2.middleware.subject.SubjectNotUniqueException;
/**
* utility methods for grouper
*
* @author mchyzer
*
*/
public class GrouperUiUtils {
/**
* get the source IP address or null if cant
* @return IP address
*/
public static String j2eeRetrieveSourceIpAddress() {
HttpServletRequest httpServletRequest = GrouperUiFilter.retrieveHttpServletRequest();
return httpServletRequest == null ? null : httpServletRequest.getRemoteAddr();
}
/**
* convert seconds to string
* @param seconds
* @return seconds in string (e.g. 4 hours, 32 minutes, 56 seconds
*/
public static String convertSecondsToString(int seconds) {
if (seconds < 0) {
return "";
}
if (seconds < 60) {
return seconds + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalSeconds");
}
// http://stackoverflow.com/questions/11357945/java-convert-seconds-into-day-hour-minute-and-seconds-using-timeunit
int days = (int)TimeUnit.SECONDS.toDays(seconds);
int hours = (int)(TimeUnit.SECONDS.toHours(seconds) - (TimeUnit.SECONDS.toDays(seconds) *24));
int minutes = (int)(TimeUnit.SECONDS.toMinutes(seconds) - (TimeUnit.SECONDS.toHours(seconds)* 60));
int secondsRemainder = (int)(TimeUnit.SECONDS.toSeconds(seconds) - (TimeUnit.SECONDS.toMinutes(seconds) *60));
if (seconds < 3600) {
return minutes + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalMinutes")
+ " " + secondsRemainder + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalSeconds");
}
if (seconds < 86400) {
return hours + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalHours")
+ " " + minutes + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalMinutes")
+ " " + secondsRemainder + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalSeconds");
}
return days + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalDays")
+ " " + hours + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalHours")
+ " " + minutes + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalMinutes")
+ " " + secondsRemainder + " " + TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalSeconds");
}
/**
* handle a veto, maybe put a message on screen if this is a veto
* @param guiResponseJs
* @param cause
* @return true if handling veto
*/
public static boolean vetoHandle(GuiResponseJs guiResponseJs, Throwable cause) {
String errorMessage = vetoHandleErrorMessage(cause);
if (errorMessage != null) {
guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error,
errorMessage));
return true;
}
return false;
}
public static String vetoHandleErrorMessage(Throwable cause) {
Throwable causeCause = cause == null ? null : cause.getCause();
Throwable causeCauseCause = causeCause == null ? null : causeCause.getCause();
HookVeto hookVeto = (cause instanceof HookVeto) ? (HookVeto)cause : null;
hookVeto = ((hookVeto == null) && (causeCause instanceof HookVeto)) ? (HookVeto)causeCause : hookVeto;
hookVeto = ((hookVeto == null) && (causeCauseCause instanceof HookVeto)) ? (HookVeto)causeCauseCause : hookVeto;
if (hookVeto != null) {
String messageToScreen = TextContainer.textOrNull(hookVeto.getReasonKey());
//make sure the key is in there
if (StringUtils.isEmpty(messageToScreen)) {
messageToScreen = hookVeto.getReason();
}
if (!StringUtils.isBlank(messageToScreen)) {
return messageToScreen;
}
}
return null;
}
/**
* if search string valid
* @param searchString
* @return true if the search string is valid
*/
public static boolean searchStringValid(String searchString) {
//check by splitting and trimming
boolean searchOk = false;
if (searchString != null && searchString.length() >= 2) {
boolean hasOneToken = false;
searchOk = true;
String[] tokens = GrouperUtil.splitTrim(searchString, " ");
for (String token : tokens) {
if (token.length() < 2) {
searchOk = false;
break;
}
hasOneToken = true;
}
if (!hasOneToken) {
searchOk = false;
}
}
return searchOk;
}
/**
* compute a url of a resource
* @param resourceName
* @param canBeNull if cant be null, throw runtime
* @return the URL
*/
public static URL computeUrl(String resourceName, boolean canBeNull) {
//get the url of the navigation file
//TODO move this to grouperutil
ClassLoader cl = classLoader();
URL url = null;
try {
url = cl.getResource(resourceName);
} catch (NullPointerException npe) {
String error = "computeUrl() Could not find resource file: " + resourceName;
throw new RuntimeException(error, npe);
}
if (!canBeNull && url == null) {
throw new RuntimeException("Cant find resource: " + resourceName);
}
return url;
}
/**
* fast class loader
* @return the class loader
*/
public static ClassLoader classLoader() {
return GrouperUiUtils.class.getClassLoader();
}
/**
* Field lastId.
*/
private static char[] lastId = convertLongToStringSmall(new Date().getTime())
.toCharArray();
/** cache the properties read from resource */
private static Map resourcePropertiesCache = new HashMap();
/**
* read properties from a resource, dont modify the properties returned since they are cached
* @param resourceName
* @return the properties
*/
public synchronized static Properties propertiesFromResourceName(String resourceName) {
Properties properties = resourcePropertiesCache.get(resourceName);
if (properties == null) {
properties = new Properties();
//TODO move this to grouperutil
URL url = computeUrl(resourceName, true);
InputStream inputStream = null;
try {
inputStream = url.openStream();
properties.load(inputStream);
} catch (Exception e) {
throw new RuntimeException("Problem with resource: '" + resourceName + "'");
} finally {
GrouperUtil.closeQuietly(inputStream);
}
}
return properties;
}
/**
* get a unique string identifier based on the current time,
* this is not globally unique, just unique for as long as this
* server is running...
*
* @return String
*/
public static String uniqueId() {
//this needs to be threadsafe since we are using a static field
synchronized (GrouperUiUtils.class) {
lastId = incrementStringInt(lastId);
}
return String.valueOf(lastId);
}
/**
* this method takes a long (less than 62) and converts it to a 1 character
* string (a-z, A-Z, 0-9)
*
* @param theLong
* is the long (less than 62) to convert to a 1 character string
*
* @return a one character string
*/
public static String convertLongToChar(long theLong) {
if ((theLong < 0) || (theLong >= 62)) {
throw new RuntimeException("StringUtils.convertLongToChar() "
+ " invalid input (not >=0 && <62: " + theLong);
} else if (theLong < 26) {
return "" + (char) ('a' + theLong);
} else if (theLong < 52) {
return "" + (char) ('A' + (theLong - 26));
} else {
return "" + (char) ('0' + (theLong - 52));
}
}
/**
* this method takes a long (less than 36) and converts it to a 1 character
* string (A-Z, 0-9)
*
* @param theLong
* is the long (less than 36) to convert to a 1 character string
*
* @return a one character string
*/
public static String convertLongToCharSmall(long theLong) {
if ((theLong < 0) || (theLong >= 36)) {
throw new RuntimeException("StringUtils.convertLongToCharSmall() "
+ " invalid input (not >=0 && <36: " + theLong);
} else if (theLong < 26) {
return "" + (char) ('A' + theLong);
} else {
return "" + (char) ('0' + (theLong - 26));
}
}
/**
* convert a long to a string by converting it to base 62 (26 lower, 26 upper,
* 10 digits)
*
* @param theLong
* is the long to convert
*
* @return the String conversion of this
*/
public static String convertLongToString(long theLong) {
long quotient = theLong / 62;
long remainder = theLong % 62;
if (quotient == 0) {
return convertLongToChar(remainder);
}
StringBuffer result = new StringBuffer();
result.append(convertLongToString(quotient));
result.append(convertLongToChar(remainder));
return result.toString();
}
/**
* convert a long to a string by converting it to base 36 (26 upper, 10
* digits)
*
* @param theLong
* is the long to convert
*
* @return the String conversion of this
*/
public static String convertLongToStringSmall(long theLong) {
long quotient = theLong / 36;
long remainder = theLong % 36;
if (quotient == 0) {
return convertLongToCharSmall(remainder);
}
StringBuffer result = new StringBuffer();
result.append(convertLongToStringSmall(quotient));
result.append(convertLongToCharSmall(remainder));
return result.toString();
}
/**
* increment a character (A-Z then 0-9)
*
* @param theChar
*
* @return the value
*/
public static char incrementChar(char theChar) {
if (theChar == 'Z') {
return '0';
}
if (theChar == '9') {
return 'A';
}
return ++theChar;
}
/**
* Increment a string with A-Z and 0-9 (no lower case so case insensitive apps
* like windows IE will still work)
*
* @param string
*
* @return the value
*/
public static char[] incrementStringInt(char[] string) {
if (string == null) {
return string;
}
//loop through the string backwards
int i = 0;
for (i = string.length - 1; i >= 0; i--) {
char inc = string[i];
inc = incrementChar(inc);
string[i] = inc;
if (inc != 'A') {
break;
}
}
//if we are at 0, then it means we hit AAAAAAA (or more)
if (i < 0) {
return ("A" + new String(string)).toCharArray();
}
return string;
}
/**
* get a cookie based on name or null if not there
* @param cookieName
* @param cookies (from httprequest)
* @return the cookie
*/
public static Cookie retrieveCookie(String cookieName, Cookie[] cookies) {
cookies = cookies == null ? new Cookie[0] : cookies;
for (Cookie cookie : cookies) {
if (StringUtils.equals(cookie.getName(), cookieName)) {
return cookie;
}
}
return null;
}
/**
* get a cookie value (null if not there)
* @param cookieName
* @param cookies (from httprequest)
* @return the cookie value
*/
public static String cookieValue(String cookieName, Cookie[] cookies) {
Cookie cookie = retrieveCookie(cookieName, cookies);
return cookie == null ? null : cookie.getName();
}
/**
* kill a cookie if it is there
* @param cookieName
* @param cookies (from httprequest)
* @param httpServletResponse is response for adding cookies
*/
public static void killCookie(String cookieName, Cookie[] cookies, HttpServletResponse httpServletResponse) {
Cookie cookie = retrieveCookie(cookieName, cookies);
if (cookie != null) {
cookie.setMaxAge(0);
cookie.setValue(null);
httpServletResponse.addCookie(cookie);
}
}
/** pattern of a subject: sourceId||||subjectId (slashes escape the pipes) */
public static Pattern subjectPattern = Pattern.compile("^(.*)\\|\\|\\|\\|(.*)$");
/**
* dhtmlx option end of xml
*/
public static final String DHTMLX_OPTIONS_END = "";
/**
* dhtmlx option start of xml
*/
public static final String DHTMLX_OPTIONS_START = "\n\n";
//utf-8, iso-8859-1
/**
* logger
*/
private static final Log LOG = edu.internet2.middleware.grouper.util.GrouperUtil.getLog(GrouperUiUtils.class);
/**
* web service format string
*/
private static final String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss.SSS";
/** subject image map */
private static Map subjectImageMap = null;
/** map from source to subject screen EL */
private static Map subjectToScreenEl = null;
/** map from source to subject screen EL */
private static Map subjectToScreenEl2 = null;
/** map from source to subject icon EL */
private static Map subjectToIconEl2 = null;
/** map from source to subject screen EL the long version */
private static Map subjectToScreenElLong = null;
/** class file dir cached */
public static File classFileDir = null;
/** array for converting javascript to string */
private static final String[] JAVASCRIPT_REPLACE = new String[]{"&","<",">","\\'","""};
/** array for converting javascript to string */
private static final String[] JAVASCRIPT_SEARCH = new String[]{"&","<",">","'","\""};
/**
* get request params (e.g. for logging), in one string, abbreviated
* @return request params
*/
@SuppressWarnings("unchecked")
public static String requestParams() {
HttpServletRequest httpServletRequest = GrouperUiFilter.retrieveHttpServletRequest();
StringBuilder requestParams = new StringBuilder();
Map parameterMap = GrouperUtil.nonNull(httpServletRequest.getParameterMap());
for (Object nameObject : parameterMap.keySet()) {
String name = (String)nameObject;
Object object = parameterMap.get(name);
requestParams.append(name).append(" : ");
if (object == null) {
requestParams.append("null");
} else if (object instanceof String[]) {
String[] values = (String[])object;
for (int i=0;i<50;i++) {
if (i >= values.length) {
break;
}
requestParams.append(StringUtils.abbreviate(values[i], 50)).append(", ");
}
if (values.length > 50) {
requestParams.append("[more than 50 params...]");
}
}
requestParams.append("; ");
}
return requestParams.toString();
}
/**
* append an error to the request, will be logged and maybe emailed to admins
* @param error
*/
public static void appendErrorToRequest(String error) {
HttpServletRequest httpServletRequest = GrouperUiFilter.retrieveHttpServletRequest();
String existingError = (String)httpServletRequest.getAttribute("error");
String newError = error;
if (!StringUtils.isBlank(existingError)) {
newError = existingError + "\n\n" + error;
}
httpServletRequest.setAttribute("error", newError);
}
/**
* find subjects which are members of a group, and return those members. Do this in few queries
* since we might run out of bind variables
*
* NOTE, I DONT THINK IMMEDIATE ONLY AS FALSE WILL WORK, WILL ONLY WORK WITH IMMEDIATE ONLY
*
* @param grouperSession
* @param group
* @param subjects
* @param immediateOnly true for only immediate, false for immediate and effective
* @return the members or none if not allowed
*/
public static Set convertSubjectsToMembers(GrouperSession grouperSession,
Group group, Set subjects, boolean immediateOnly) {
if (!PrivilegeHelper.canViewMembers(grouperSession, group, Group.getDefaultList())) {
return new LinkedHashSet();
}
//lets do this in batches
List subjectsList = GrouperUtil.listFromCollection(subjects);
int numberOfBatches = GrouperUtil.batchNumberOfBatches(subjectsList, 100);
Set result = new LinkedHashSet();
for (int i=0;i subjectBatch = GrouperUtil.batchList(subjectsList, 100, i);
// select distinct gm.*
// from grouper_members gm, grouper_memberships gms
// where gm.id = gms.member_id
// and gms.field_id = 'abc' and gms.owner_id = '123'
// and gm.subject_id in ('123','234')
// and mship_type = 'immediate'
//lets turn the subjects into subjectIds
Set subjectIds = new LinkedHashSet();
for (Subject currentSubject : subjectBatch) {
subjectIds.add(currentSubject.getId());
}
if (subjectIds.size() == 0) {
continue;
}
ByHqlStatic byHqlStatic = HibernateSession.byHqlStatic();
StringBuilder query = new StringBuilder("select gm " +
"from Member gm, ImmediateMembershipEntry gms " +
"where gm.uuid = gms.memberUuid " +
"and gms.fieldId = :fieldId " +
"and gms.ownerGroupId = :ownerId " +
(immediateOnly ? "and gms.type = 'immediate' " : "") +
"and gm.subjectIdDb in (");
//add all the uuids
byHqlStatic.setString("fieldId", Group.getDefaultList().getUuid());
byHqlStatic.setString("ownerId", group.getUuid());
byHqlStatic.setCollectionInClause(query, subjectIds);
query.append(")");
List currentListPerhapsWithExtra = byHqlStatic.createQuery(query.toString())
.list(Member.class);
//could have two subjects with different sources with same subject id... weed those out
Set currentMembers = removeOverlappingSubjects(currentListPerhapsWithExtra, subjectBatch);
result.addAll(currentMembers);
}
return result;
}
/**
* remove duplicates
* @param members
*/
public static void memberRemoveDuplicates(List members) {
if (members == null) {
return;
}
Iterator iterator = members.iterator();
//keep track of ones we have seen
Set uniqueSubjects = new LinkedHashSet();
//loop through all items
while(iterator.hasNext()) {
Member member = iterator.next();
//get the key
MultiKey subjectKey = new MultiKey(member.getSubjectSourceId(), member.getSubjectId());
//see if already seen
if (uniqueSubjects.contains(subjectKey)) {
//remove if so
iterator.remove();
} else {
uniqueSubjects.add(subjectKey);
}
}
}
/**
* remove duplicates
* @param subjects
*/
public static void subjectRemoveDuplicates(List subjects) {
if (subjects == null) {
return;
}
Iterator iterator = subjects.iterator();
//keep track of ones we have seen
Set uniqueSubjects = new LinkedHashSet();
//loop through all items
while(iterator.hasNext()) {
Subject subject = iterator.next();
//get the key
MultiKey subjectKey = new MultiKey(subject.getId(), subject.getSource().getId());
//see if already seen
if (uniqueSubjects.contains(subjectKey)) {
//remove if so
iterator.remove();
} else {
uniqueSubjects.add(subjectKey);
}
}
}
/**
* remove overlapping subjects from two lists. i.e. if first is existing, and
* second is new, then if we are replacing all members of the group, then the first would
* end up being the ones to remove, and the second is the one to add.
* this will also remove dupes
* @param first
* @param second
* @return the overlap, never null
*/
public static Set removeOverlappingSubjects(List first, List second) {
Set overlaps = new LinkedHashSet();
//lets add them to hashes (multikeys)
//multikey is the sourceId and subjectId
//we use a listordered set so it is a set and a list all in one, unfortunately no generics
ListOrderedSet firstHashes = new ListOrderedSet();
ListOrderedSet secondHashes = new ListOrderedSet();
memberRemoveDuplicates(first);
subjectRemoveDuplicates(second);
//if null no overlap
if (GrouperUtil.length(first) == 0 || GrouperUtil.length(second) == 0) {
return overlaps;
}
//put these both in hashes, keep track of hashes
for (Member member : first) {
firstHashes.add(new MultiKey(member.getSubjectSourceId(), member.getSubjectId()));
}
for (Subject subject : second) {
secondHashes.add(new MultiKey(subject.getSource().getId(), subject.getId()));
}
//now lets go through, and remove if it is (or was) in the other
{
int i=0;
Iterator firstIterator = first.iterator();
while (firstIterator.hasNext()) {
Member nextFirst = firstIterator.next();
MultiKey firstHash = (MultiKey)firstHashes.get(i);
if (secondHashes.contains(firstHash)) {
firstIterator.remove();
overlaps.add(nextFirst);
//lets add the subject to the Member if not already there, so we dont have to look it up again
// dont do this anymore since member doesnt have subj in it! :)
//Subject memberSubjectFirst = (Subject)GrouperUtil.fieldValue(nextFirst, "subj");
//if (memberSubjectFirst == null ) {
// int subjectIndex = secondHashes.indexOf(firstHash);
// Subject realSubject = second.get(subjectIndex);
// //a little sanity here
// if (!StringUtils.equals(realSubject.getId(), nextFirst.getSubjectId())
// || !StringUtils.equals(realSubject.getSource().getId(), nextFirst.getSubjectSourceId())) {
// throw new RuntimeException("These should be equal!!!");
// }
// GrouperUtil.assignField(nextFirst, "subj", realSubject);
//}
}
i++;
}
}
{
int i=0;
Iterator secondIterator = second.iterator();
while (secondIterator.hasNext()) {
secondIterator.next();
if (firstHashes.contains(secondHashes.get(i))) {
secondIterator.remove();
}
i++;
}
}
return overlaps;
}
/**
*
* @param members
* @return the subjects
*/
public static Set convertMembersToSubject(Set members) {
if (members == null) {
return null;
}
Set subjects = new LinkedHashSet();
for (Member member : members) {
try {
subjects.add(member.getSubject());
} catch (SubjectNotFoundException snfe) {
throw new RuntimeException("Subject not found: " + member.getSubjectSourceId() + ", " + member.getSubjectId());
}
}
return subjects;
}
/**
*
* @param a
* @param b
* @param ignoreCase if case shoul dbe ignored
* @return 0, 1,-1
*/
public static int compare(String a, String b, boolean ignoreCase) {
if (a==b) {
return 0;
}
if (a == null) {
return -1;
}
if (b == null) {
return 1;
}
if (ignoreCase) {
return a.toLowerCase().compareTo(b.toLowerCase());
}
return a.compareTo(b);
}
/**
* keep a-z, A-Z, 0-9, underscore, dash
* @param string
* @return the string (or empty if nothing left
*/
public static String stripNonFilenameChars(String string) {
if (string == null) {
return "";
}
StringBuilder result = new StringBuilder();
//strip non filename chars
for (int i=0;i= 'a' && theChar <= 'z') || (theChar >= 'A' && theChar <= 'Z')
|| (theChar >= '0' && theChar <= '9') || theChar == '_' || theChar == '-') {
result.append(theChar);
}
}
return result.toString();
}
/**
* lookup something in nav.properties (localized), substitute args
* @param key
* @param blankIfNotFound true if null or blank if not found, else it will return ???key???
* @param escapeHtmlArgs if html should be escaped from args
* @param args
* @return the message
*/
public static String message(String key, boolean blankIfNotFound, boolean escapeHtmlArgs, Object... args) {
String message = message(key, true);
//handle blank
if (StringUtils.isBlank(message)) {
return message(key, blankIfNotFound);
}
if (GrouperUtil.length(args) == 0) {
return message;
}
for (int i=0;i subjectsSortedPaged(Set subjects, QueryPaging queryPaging, String searchTerm) {
subjects = GrouperUtil.nonNull(subjects);
//if we are getting size, set it
if (queryPaging.isDoTotalCount()) {
queryPaging.setTotalRecordCount(subjects.size());
queryPaging.calculateIndexes();
}
if (subjects.size() == 0) {
return subjects;
}
int maxSubjectSortSize = GrouperUiConfig.retrieveConfig().propertyValueInt("comparator.sort.limit", 400);
//see if we should sort
if (subjects.size() < maxSubjectSortSize) {
//lets convert to a wrapper which has a sort field
List subjectsSorted = new ArrayList();
for (Subject subject : subjects) {
subjectsSorted.add(new SubjectSortWrapper(subject));
}
//sort it
Collections.sort(subjectsSorted);
//convert back to set
subjects = new LinkedHashSet(subjectsSorted);
//lets bring more important things to the top
subjects = SubjectHelper.sortSetForSearch(subjects, searchTerm);
}
//get the page
int numberOfPages = GrouperUtil.batchNumberOfBatches(subjects.size(), queryPaging.getPageSize());
//dont let a dynamic query let the page number go off the screen
int pageNumber = numberOfPages >= queryPaging.getPageNumber() ? queryPaging.getPageNumber() : numberOfPages;
List subjectsList = GrouperUtil.batchList(GrouperUtil.listFromCollection(subjects),
queryPaging.getPageSize(), pageNumber-1);
//convert yet again back to set
subjects = new LinkedHashSet(subjectsList);
return subjects;
}
/**
*
* @param members to sort and page
* @param queryPaging
* @return the set of subject, or empty set (never null)
*/
@SuppressWarnings("unchecked")
public static Set membersSortedPaged(Set members, QueryPaging queryPaging) {
members = GrouperUtil.nonNull(members);
//if we are getting size, set it
if (queryPaging.isDoTotalCount()) {
queryPaging.setTotalRecordCount(members.size());
queryPaging.calculateIndexes();
}
if (members.size() == 0) {
return members;
}
int maxSubjectSortSize = GrouperUiConfig.retrieveConfig().propertyValueInt("comparator.sort.limit", 200);
//see if we should sort
if (members.size() < maxSubjectSortSize) {
List membersSorted = new ArrayList();
//lets convert to a wrapper which has a sort field
for (Member member : members) {
membersSorted.add(new MemberSortWrapper(member));
}
//sort it
Collections.sort(membersSorted);
//convert back to set
members = new LinkedHashSet();
for (MemberSortWrapper memberSortWrapper : membersSorted) {
members.add(memberSortWrapper.getWrappedMember());
}
}
//get the page
int numberOfPages = GrouperUtil.batchNumberOfBatches(members.size(), queryPaging.getPageSize());
//dont let a dynamic query let the page number go off the screen
int pageNumber = numberOfPages >= queryPaging.getPageNumber() ? queryPaging.getPageNumber() : numberOfPages;
List membersList = GrouperUtil.batchList(new ArrayList(members), queryPaging.getPageSize(), pageNumber-1);
//convert yet again back to set
members = new LinkedHashSet(membersList);
return members;
}
/**
* convert a subject to string for screen
* @param subject
* @return the string
*/
public static String convertSubjectToValue(Subject subject) {
String value = subject.getSource().getId() + "||||" + subject.getId();
return value;
}
/**
* convert a subject to string for screen
* @param subject
* @return the string
*/
public static String convertSubjectToLabel(Subject subject) {
return convertSubjectToLabelConfigured(subject, false);
}
/**
* convert a subject to string for screen e.g. for tooltip
* @param subject
* @return the string
*/
public static String convertSubjectToLabelLong(Subject subject) {
return convertSubjectToLabelConfigured(subject, true);
}
/**
* find a subject based on search string. must be sourceId||||subjectId
* or a subjectId or subjectIdentifier which is unique
* @param searchString
* @param exceptionIfNotFound
* @return the subject
* @throws SubjectNotFoundException
* @throws SubjectNotUniqueException
* @throws SourceUnavailableException
*/
public static Subject findSubject(String searchString, boolean exceptionIfNotFound)
throws SubjectNotFoundException, SubjectNotUniqueException, SourceUnavailableException {
if (searchString == null) {
throw new SubjectNotFoundException("Cant find null string");
}
Matcher matcher = subjectPattern.matcher(searchString);
//if it matches sourceId||||subjectId then we know exactly which subject
if (matcher.matches()) {
String sourceId = matcher.group(1);
String subjectId = matcher.group(2);
return SubjectFinder.findByIdAndSource(subjectId, sourceId, exceptionIfNotFound);
}
//if not, then try to get by subjectId or identifier
try {
return SubjectFinder.findByIdOrIdentifier(searchString, exceptionIfNotFound);
} catch (SubjectNotUniqueException snue) {
if (exceptionIfNotFound) {
throw snue;
}
//ignore
}
if (exceptionIfNotFound) {
throw new RuntimeException("Cant find subject: '" + searchString + "'");
}
return null;
}
/**
* make one dhtmlx option
* @param result to append to
* @param value
* @param label
* @param imageUrl
*/
public static void dhtmlxOptionAppend(StringBuilder result, String value, String label, String imageUrl) {
//
result.append(" \n");
}
/**
* Print some text to the screen
* @param string
* @param httpContentType e.g. "text/html", "text/xml"
* @param includeXmlTag
* @param includeHtmlTag
*
*/
public static void printToScreen(String string, HttpContentType httpContentType,
boolean includeXmlTag, boolean includeHtmlTag) {
HttpServletResponse response = GrouperUiFilter.retrieveHttpServletResponse();
//say it is HTML, if not too late
if (httpContentType != null && !response.isCommitted()) {
response.setContentType(httpContentType.getContentType());
}
//just write some stuff
PrintWriter out = null;
try {
out = response.getWriter();
} catch (Exception e) {
throw new RuntimeException("Cant get response.getWriter: ", e);
}
if (includeXmlTag) {
out.println("\n"
+ "\n");
}
//see if we should add etc
if (includeHtmlTag) {
out.println("");
out.println(string);
out.println("");
} else {
out.println(string);
}
out.close();
}
/**
* escape single quotes for javascript
* @param input
* @return the escaped string
*/
public static String escapeSingleQuotes(String input) {
return StringUtils.replace(input, "'", "\\'");
}
/**
* get a cookie value by name, null if not there
* @param prefix
*/
public static void removeCookiesByPrefix(String prefix) {
HttpServletResponse httpServletResponse = GrouperUiFilter.retrieveHttpServletResponse();
List cookies = findCookiesByPrefix(prefix);
for (Cookie cookie : cookies) {
cookie.setMaxAge(0);
//note: this is needed for websec cookies... is it for all cookies?
cookie.setPath("/");
cookie.setValue("");
httpServletResponse.addCookie(cookie);
if (httpServletResponse.isCommitted()) {
LOG.error("Trying to kill cookie: " + cookie.getName() + ", but the response is committed!", new RuntimeException("stack"));
}
}
}
/**
* find a cookie or empty list if cant find
* @param name
* @return the cookies or empty list if not found
*/
public static List findCookiesByPrefix(String name) {
HttpServletRequest httpServletRequest = GrouperUiFilter.retrieveHttpServletRequest();
StringBuilder allCookies = null;
boolean isDebug = LOG.isDebugEnabled();
if (isDebug) {
allCookies = new StringBuilder("Looking for cookie with prefix: '" + name + "'");
}
List cookieList = new ArrayList();
Cookie[] cookies = httpServletRequest.getCookies();
//go through all cookies and find the cookie by name
int cookiesLength = GrouperUtil.length(cookies);
for (int i=0;i theSubjectImageMap = new HashMap();
Properties propertiesSettings = GrouperUiConfig.retrieveConfig().properties();
int index = 0;
while (true) {
String sourceName = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.subjectImg.sourceId." + index);
String imageName = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.subjectImg.image." + index);
if (StringUtils.isBlank(imageName)) {
break;
}
theSubjectImageMap.put(sourceName, imageName);
index++;
}
subjectImageMap = theSubjectImageMap;
}
String imageName = subjectImageMap.get(sourceId);
if (!StringUtils.isBlank(imageName)) {
imageName = "../../grouperExternal/public/assets/images/" + imageName;
}
return imageName;
}
/**
* get a label from a subject based on media.properties
* @param subject
* @return the relative path to image path
*/
public static String convertSubjectToLabelConfigured(Subject subject) {
return convertSubjectToLabelConfigured(subject, true);
}
/**
*
* @param args
*/
public static void main(String[] args) {
GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() {
@Override
public Object callback(GrouperSession grouperSession) throws GrouperSessionException {
Subject subject = SubjectFinder.findByIdentifierAndSource("edu:someGroup", "g:gsa", true);
Map variableMap = new HashMap();
variableMap.put("subject", subject);
variableMap.put("grouperUiUtils", new GrouperUiUtils());
String result = GrouperUtil.substituteExpressionLanguage("${subject.getAttributeValue('displayName')}", variableMap);
System.out.println(result);
return null;
}
});
}
/**
* source id to an id to use to look up thing in the text file for the source (if special chars in source id)
*/
private static GrouperCache sourceIdToSourceTextIdCache = null;
/**
* source id to an id to use to look up thing in the text file for the source (if special chars in source id)
* (use the source id if not configured to be different)
* lazy load
* @return sourceId cache
*/
private static GrouperCache sourceIdToSourceTextIdCache() {
if (sourceIdToSourceTextIdCache == null) {
synchronized(GrouperStartup.class) {
if (sourceIdToSourceTextIdCache == null) {
sourceIdToSourceTextIdCache = new GrouperCache(
"edu.internet2.middleware.grouper.ui.util.GrouperUiUtils.sourceIdToSourceTextIdCache",
2000, false, 60, 60, false);
}
}
}
return sourceIdToSourceTextIdCache;
}
/**
* convert a source id to a text id (use the source id if not configured to be different)
* @param sourceId
* @return the text id
*/
public static String convertSourceIdToTextId(String sourceId) {
GrouperCache theSourceIdToTextIdCache = sourceIdToSourceTextIdCache();
String textId = theSourceIdToTextIdCache.get(sourceId);
//this is optional, if not configured, then just use the sourceId
if (!StringUtils.isBlank(textId)) {
return textId;
}
return sourceId;
}
/**
* get a label from a subject based on media.properties
* @param subject
* @param tryLong if should see if there is a long version first
* @return the relative path to image path
*/
public static String convertSubjectToLabelConfigured(Subject subject, boolean tryLong) {
if (subject == null) {
return "";
}
//see if it is already computed
if (subject instanceof SubjectSortWrapper) {
return ((SubjectSortWrapper)subject).getScreenLabelLong();
}
if (subjectToScreenEl == null) {
{
Map theSubjectToScreenEl = new HashMap();
Properties propertiesSettings = GrouperUiConfig.retrieveConfig().properties();
int index = 0;
while (true) {
String sourceName = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.subjectImg.sourceId." + index);
String screenEl = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.subjectImg.screenEl." + index);
if (StringUtils.isBlank(sourceName)) {
break;
}
if (!StringUtils.isBlank(screenEl)) {
theSubjectToScreenEl.put(sourceName, screenEl);
}
index++;
}
subjectToScreenEl = theSubjectToScreenEl;
}
{
Map theSubjectToScreenElLong = new HashMap();
Properties propertiesSettings = GrouperUiConfig.retrieveConfig().properties();
int index = 0;
while (true) {
String sourceName = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.subjectImgLong.sourceId." + index);
String screenElLong = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.subjectImgLong.screenEl." + index);
if (StringUtils.isBlank(sourceName)) {
break;
}
if (!StringUtils.isBlank(screenElLong)) {
theSubjectToScreenElLong.put(sourceName, screenElLong);
}
index++;
}
subjectToScreenElLong = theSubjectToScreenElLong;
}
}
String screenEl = null;
if (tryLong) {
screenEl = subjectToScreenElLong.get(subject.getSource().getId());
}
if (StringUtils.isBlank(screenEl)) {
screenEl = subjectToScreenEl.get(subject.getSource().getId());
}
if (StringUtils.isBlank(screenEl)) {
String label = subject.getDescription();
if (StringUtils.isBlank(label)) {
label = subject.getSourceId() + " - " + subject.getId() + " - " + subject.getName();
}
return label;
}
//run the screen EL
Map variableMap = new HashMap();
variableMap.put("subject", subject);
variableMap.put("grouperUiUtils", new GrouperUiUtils());
String result = GrouperUtil.substituteExpressionLanguage(screenEl, variableMap, false, true, true);
return result;
}
/**
* get a v2 label from a subject based on grouper-ui.properties
* @param subject
* @return the subject html string
*/
public static String convertSubjectToLabelHtmlConfigured2(Subject subject) {
if (subject == null) {
return "";
}
if (subjectToScreenEl2 == null) {
{
Map theSubjectToScreenEl = new HashMap();
Properties propertiesSettings = GrouperUiConfig.retrieveConfig().properties();
int index = 0;
while (true) {
String sourceName = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.screenLabel2.sourceId." + index);
String screenEl = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.screenLabel2.screenEl." + index);
if (StringUtils.isBlank(sourceName)) {
break;
}
if (!StringUtils.isBlank(screenEl)) {
theSubjectToScreenEl.put(sourceName, screenEl);
}
index++;
}
subjectToScreenEl2 = theSubjectToScreenEl;
}
}
String screenEl = subjectToScreenEl2.get(subject.getSource().getId());
if (StringUtils.isBlank(screenEl)) {
String label = subject.getName();
if (StringUtils.isBlank(label)) {
label = subject.getSourceId() + " - " + subject.getId();
}
return label;
}
//run the screen EL
Map variableMap = new HashMap();
variableMap.put("subject", subject);
variableMap.put("grouperUiUtils", new GrouperUiUtils());
String result = GrouperUtil.substituteExpressionLanguage(screenEl, variableMap, false, true, true);
return result;
}
/**
* get a v2 label from a subject based on grouper-ui.properties
* @param subject
* @return the subject html string
*/
public static String convertSubjectToIconHtmlConfigured2(Subject subject) {
if (subject == null) {
return "";
}
if (subjectToIconEl2 == null) {
{
Map theSubjectToIconEl = new HashMap();
Properties propertiesSettings = GrouperUiConfig.retrieveConfig().properties();
String defaultIconEl = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.screenSubjectIcon2.screenHtmlEl.default");
if (StringUtils.isBlank(defaultIconEl)) {
defaultIconEl = "${' '}"; // fallback in case grouper-ui.base.properties wasn't upgraded
}
String defaultIconHtml = GrouperUtil.substituteExpressionLanguage(defaultIconEl, new HashMap(), false, true, true);
theSubjectToIconEl.put("", defaultIconHtml); // the default icon will be keyed under subject ID ""
int index = 0;
while (true) {
String sourceName = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.screenSubjectIcon2.sourceId." + index);
String screenEl = GrouperUtil.propertiesValue(propertiesSettings,
"grouperUi.screenSubjectIcon2.screenHtmlEl." + index);
if (StringUtils.isBlank(sourceName)) {
break;
}
if (StringUtils.isBlank(screenEl)) {
theSubjectToIconEl.put(sourceName, defaultIconHtml);
} else {
theSubjectToIconEl.put(sourceName, screenEl);
}
index++;
}
subjectToIconEl2 = theSubjectToIconEl;
}
}
String iconEl = subjectToIconEl2.get(subject.getSource().getId());
if (StringUtils.isBlank(iconEl)) {
return subjectToIconEl2.get(""); //default icon
}
//run the screen EL
Map variableMap = new HashMap();
variableMap.put("subject", subject);
variableMap.put("grouperUiUtils", new GrouperUiUtils());
String result = GrouperUtil.substituteExpressionLanguage(iconEl, variableMap, false, true, true);
return result;
}
/**
* get the class file dir
* @return the class file dir
*/
public static File classFileDir() {
if (classFileDir == null) {
classFileDir = GrouperUtil.fileFromResourceName("grouperUiText.properties").getParentFile();
}
return classFileDir;
}
/**
* list files with a certain extension. Note, there cannot be more than 10000
* files or exception will be throws
* @param dir
* @param extension if this is the empty string it should list all
* @return the array of files
*/
public static List listFilesByExtensionRecursive(File dir, String extension) {
List theList = new ArrayList();
listFilesByExtensionRecursiveHelper(dir, extension, theList);
return theList;
}
/**
* list files with a certain extension
* @param dir
* @param extension if this is the empty string it should list all
* @param theList is the current list to append to
*/
public static void listFilesByExtensionRecursiveHelper(File dir, String extension,
List theList) {
//see if its a directory
if (!dir.exists()) {
throw new RuntimeException("The directory: " + dir + " does not exist");
}
if (!dir.isDirectory()) {
throw new RuntimeException("The directory: " + dir + " is not a directory");
}
//get the files into a list
File[] allFiles = listFilesByExtension(dir, extension);
//loop through the array
for (int i = 0; i < allFiles.length; i++) {
if (StringUtils.contains(allFiles[i].getName(), "..")) {
continue; //dont go to the parent directory
}
if (allFiles[i].isFile()) {
//make sure not too big
if (theList.size() > 10000) {
throw new RuntimeException("File list too large: " + dir.getAbsolutePath()
+ ", " + extension);
}
//add to list
theList.add(allFiles[i]);
} else {
//ignore, we will do all dirs in good time
}
}
//do all the subdirs
File[] allSubdirs = listSubdirs(dir);
int allSubdirsLength = allSubdirs == null ? 0 : allSubdirs.length;
for (int i = 0; i < allSubdirsLength; i++) {
listFilesByExtensionRecursiveHelper(allSubdirs[i], extension, theList);
}
}
/**
* get the subdirs of a dir (not ..)
* @param dir
* @return the dirs
*/
public static File[] listSubdirs(File dir) {
//see if its a directory
if (!dir.exists()) {
throw new RuntimeException("The directory: " + dir + " does not exist");
}
if (!dir.isDirectory()) {
throw new RuntimeException("The directory: " + dir + " is not a directory");
}
File[] subdirs = dir.listFiles(new FileFilter() {
public boolean accept(File pathname) {
if (StringUtils.contains(pathname.getName(), "..")) {
return false; //dont go to the parent directory
}
//allow dirs
if (pathname.isDirectory()) {
return true;
}
//must not be a dir
return false;
}
});
return subdirs;
}
/**
* list files with a certain extension
* @param dir
* @param extension if this is the empty string it should list all
* @return the array of files
*/
public static File[] listFilesByExtension(File dir, String extension) {
final String finalExtension = extension;
FilenameFilter fileFilter = new FilenameFilter() {
/*
* @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
*/
public boolean accept(File theDir, String name) {
if ((name != null) && name.endsWith(finalExtension)) {
//doubt we would ever look for .., but in case
if (StringUtils.contains(finalExtension, "..")) {
return true;
}
//if the file is .., then its not what we are looking for
if (StringUtils.contains(name, "..")) {
return false;
}
return true;
}
return false;
}
};
return dir.listFiles(fileFilter);
}
/**
* convert a boolean to a T or F
*
* @param theBoolean
* @return the one char booloean string
*/
public static String booleanToStringOneChar(Boolean theBoolean) {
if (theBoolean == null) {
return null;
}
return theBoolean ? "T" : "F";
}
/**
* convert a date to a string using the standard web service pattern
* yyyy/MM/dd HH:mm:ss.SSS Note that HH is 0-23
*
* @param date
* @return the string, or null if the date is null
*/
public static String dateToString(Date date) {
if (date == null) {
return null;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
return simpleDateFormat.format(date);
}
/**
* convert a date to a string using the standard web service pattern
* yyyy/MM/dd HH:mm:ss.SSS Note that HH is 0-23
*
* @param locale
* @param date
* @return the string, or null if the date is null
*/
public static String dateToString(Locale locale, Date date) {
if (locale == null) {
return dateToString(date);
}
if (date == null) {
return null;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT, locale);
return simpleDateFormat.format(date);
}
/**
* convert a jsp to string. This doesnt work from unit tests, but will work from web requests or daemons
* @param jspName e.g. whatever.jsp, or /somePath/something.jsp
* @return the eval version of the jsp
*/
public static String convertJspToString(String jspName) {
//default is in the jsp dir
if (!jspName.contains("/")) {
jspName = "/jsp/" + jspName;
}
HttpServlet servlet = GrouperUiFilter.retrieveHttpServlet();
ServletContext servletContext = servlet.getServletContext();
//get this from context not request, since could be in daemon
RequestDispatcher dispatcher = servletContext.getRequestDispatcher(jspName);
HttpServletRequest request = GrouperUiFilter.retrieveHttpServletRequest();
HttpServletResponse response = GrouperUiFilter.retrieveHttpServletResponse();
//RequestDispatcher dispatcher = request.getRequestDispatcher(jspName);
//wrap the response so that the output goes to a string
GenericServletResponseWrapper responseWrapper = new GenericServletResponseWrapper(response);
try {
dispatcher.include(request, responseWrapper);
} catch (Exception e) {
throw new RuntimeException("Problem converting JSP to string: " + jspName, e);
}
String result = responseWrapper.resultString();
//see if we are logging
if (GrouperUiConfig.retrieveConfig().propertyValueBoolean("grouperUi.logHtml", false)) {
String logDir = GrouperUiConfig.retrieveConfig().propertyValueString("grouperUi.logHtmlDir");
if (StringUtils.isBlank(logDir)) {
throw new RuntimeException("Cant log html to file with dir to put files in: grouperUi.logHtmlDir");
}
File htmlFile = null;
String jspNameforLog = GrouperUtil.suffixAfterChar(jspName, '/');
jspNameforLog = GrouperUtil.suffixAfterChar(jspNameforLog, '\\');
logDir = GrouperUtil.stripSuffix(logDir, "/");
logDir = GrouperUtil.stripSuffix(logDir, "\\");
Date date = new Date();
String logName = logDir + File.separator + "htmlLog_"
+ new SimpleDateFormat("yyyy_MM").format(date)
+ File.separator + "day_"
+ new SimpleDateFormat("dd" + File.separator + "HH_mm_ss_SSS").format(date)
+ "_" + ((int)(1000 * Math.random())) + "_" + jspNameforLog + ".html";
htmlFile = new File(logName);
//make parents
GrouperUtil.mkdirs(htmlFile.getParentFile());
GrouperUtil.saveStringIntoFile(htmlFile, result);
}
return result;
}
/**
* Convert an XML string to HTML to display on the screen
*
* @param input
* is the XML to convert
* @param isEscape true to escape chars, false to unescape
*
* @return the HTML converted string
*/
public static String escapeHtml(String input, boolean isEscape) {
return escapeHtml(input, isEscape, true);
}
/**
* Convert an XML string to HTML to display on the screen
*
* @param input
* is the XML to convert
* @param isEscape true to escape chars, false to unescape
* @param escapeSingleQuotes true to escape single quotes too
*
* @return the HTML converted string
*/
public static String escapeHtml(String input, boolean isEscape, boolean escapeSingleQuotes) {
return GrouperUtil.escapeHtml(input, isEscape, escapeSingleQuotes);
}
/**
* Escapes XML ( ampersand, lessthan, greater than, double quote), and single quote with slash
*
* @param input
* is the XML to convert
* @param isEscape true to escape chars, false to unescape
*
* @return the Javascript converted string
*/
public static String escapeJavascript(String input, boolean isEscape) {
if (isEscape) {
return GrouperUtil.replace(input, JAVASCRIPT_SEARCH, JAVASCRIPT_REPLACE);
}
return GrouperUtil.replace(input, JAVASCRIPT_REPLACE, JAVASCRIPT_SEARCH);
}
/**
* clone a collection, shallow, do not clone all objects inside
* @param
* @param object
* @return the cloned collection
*/
@SuppressWarnings("unchecked")
public static T cloneShallow(T object) {
if (object == null) {
return null;
}
if (object instanceof ArrayList) {
return (T)((ArrayList)object).clone();
}
if (object instanceof LinkedList) {
return (T)((LinkedList)object).clone();
}
if (object instanceof HashSet) {
return (T)((HashSet)object).clone();
}
if (object instanceof LinkedHashSet) {
return (T)((LinkedHashSet)object).clone();
}
if (object instanceof HashMap) {
return (T)((HashMap)object).clone();
}
if (object instanceof LinkedHashMap) {
return (T)((LinkedHashMap)object).clone();
}
if (object instanceof TreeMap) {
return (T)((TreeMap)object).clone();
}
//cant clone
throw new RuntimeException("Unsupported object type: " + GrouperUtil.className(object));
}
/**
* Return either the root stem, or the one configured by default.browse.stem.uiv2.menu and default.browse.stem
*
* @param grouperSession the session to locate the root folder as
* @return the absolute or alternate root stem
*/
public static Stem getConfiguredRootFolder(GrouperSession grouperSession) {
Stem stem = null;
// GRP-1107 browse starting from stem configured by property:
// default.browse.stem, otherwise from root.
boolean startTreeAtDefaultStem = GrouperUiConfig.retrieveConfig().propertyValueBoolean("default.browse.stem.uiv2.menu", true);
String defaultBrowseStem = GrouperUiConfig.retrieveConfig().propertyValueString("default.browse.stem");
if (startTreeAtDefaultStem && !StringUtils.isBlank(defaultBrowseStem)) {
stem = StemFinder.findByName(grouperSession, defaultBrowseStem, false);
} else {
stem = StemFinder.findRootStem(grouperSession);
}
return stem;
}
/**
* Given a group, stem, attributeDef or attributeDefName, return an array of the quoted object ids
* from the root object (or psuedo-root if default.browse.stem is set) down to the object; e.g.,
* ["root","64f667e0f346476497b62ff3ee28e906","9f8353d4c9be4212addffe806be0841a","e41cc3e6cd194a93b4037f31a715f4ce","85fc77e648ce40968b327e2f51b35a9d"].
* The should be suitable to pass to a dijitTree set('path', pathArray) funtion to load and expand the path to the object
*
* @param grouperSession session to use to locate the root folder
* @param grouperObject the target object, will be last item in the array
* @return string representation of a Javascript array of double-quoted object ids
*/
public static String pathArrayToCurrentObject(GrouperSession grouperSession, GrouperObject grouperObject) {
Stem root = getConfiguredRootFolder(grouperSession);
Stem realRoot = StemFinder.findRootStem(grouperSession);
String rootId = "root";
List ids = new ArrayList();
ids.add(grouperObject.equals(realRoot) ? rootId : grouperObject.getId());
Stem curStem;
try {
curStem = grouperObject.getParentStem();
} catch (StemNotFoundException e) {
curStem = null; // possibly is already the root stem
}
while (curStem != null) {
ids.add(curStem.equals(realRoot) ? rootId : curStem.getId());
if (curStem.equals(root) || curStem.equals(realRoot)) {
break;
}
curStem = (curStem.isRootStem()) ? null : curStem.getParentStem();
}
Collections.reverse(ids);
ArrayNode arrayNode = GrouperUtil.jsonJacksonArrayNode();
for (String id : ids) {
arrayNode.add(id);
}
return GrouperUtil.jsonJacksonToString(arrayNode);
}
/**
* Return whether the left navigation menu should refresh on object view changes
*
* @return
*/
public static boolean isMenuRefreshOnView() {
return GrouperUiConfig.retrieveConfig().propertyValueBoolean("uiV2.refresh.menu.on.view", false);
}
/**
* @return map of custom composites
*/
public static Map getCustomCompositeUiKeys() {
final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
@SuppressWarnings("unchecked")
Map customCompositeIndexesAndUiKeys = (Map)GrouperSession.callbackGrouperSession(
GrouperSession.staticGrouperSession().internal_getRootSession(), new GrouperSessionHandler() {
@Override
public Object callback(GrouperSession grouperSession) throws GrouperSessionException {
Map temp = new LinkedHashMap();
int count = 0;
while (true) {
String uiKey = GrouperConfig.retrieveConfig().getProperty("grouper.membership.customComposite.uiKey." + count, null);
String groupName = GrouperConfig.retrieveConfig().getProperty("grouper.membership.customComposite.groupName." + count, null);
String compositeType = GrouperConfig.retrieveConfig().getProperty("grouper.membership.customComposite.compositeType." + count, null);
if (uiKey == null || groupName == null || compositeType == null) {
break;
}
Group group = GroupFinder.findByName(grouperSession, groupName, false);
if (group == null) {
// bad config
count++;
continue;
}
if (group.canHavePrivilege(loggedInSubject, AccessPrivilege.READ.getName(), false)) {
temp.put(count, uiKey);
}
count++;
}
return temp;
}
});
return customCompositeIndexesAndUiKeys;
}
}