package com.almworks.jira.structure.util;
import com.almworks.jira.structure.api.PermissionLevel;
import com.almworks.jira.structure.api.PermissionRule;
import com.atlassian.jira.config.properties.ApplicationProperties;
import com.opensymphony.user.User;
import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.util.*;
/**
* <p>Contains miscellaneous utility methods.</p>
*/
public class StructureUtil {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(StructureUtil.class);
public static final long GLOBAL_STRUCTURE_ID = 1;
public static final int MAX_PROPERTY_LENGTH = 250;
public static final La<String, Long> STRING_LONG = new La<String, Long>() {
public Long la(String argument) {
try {
return argument == null ? null : Long.parseLong(argument.trim());
} catch (NumberFormatException e) {
return null;
}
}
};
public static PermissionLevel applyPermissions(List<PermissionRule> permissions, User user,
List<Object> stack, La<Long, List<PermissionRule>> resolver, PermissionLevel pass)
{
PermissionLevel r = pass;
if (permissions != null) {
for (PermissionRule permission : permissions) {
r = permission.apply(user, r, stack, resolver);
}
}
return r;
}
public static JAXBContext createJAXBContext(Class contextClass) {
Thread thread = Thread.currentThread();
ClassLoader contextLoader = thread.getContextClassLoader();
ClassLoader[] loaders = {ClassLoader.getSystemClassLoader(), contextLoader, JAXBContext.class.getClassLoader(), contextClass.getClassLoader()};
JAXBContext context = null;
try {
context = JAXBContext.newInstance(contextClass);
} catch (JAXBException e) {
for (int i = 1; i < loaders.length; i++) {
try {
thread.setContextClassLoader(loaders[i]);
context = JAXBContext.newInstance(contextClass);
if (context != null) break;
} catch (JAXBException e2) {
// ignore
}
}
if (context == null) {
logger.error("cannot initialize JAXB context for " + contextClass + " (tried loaders: " + Arrays.asList(loaders) + ")", e);
}
} finally {
thread.setContextClassLoader(contextLoader);
}
return context;
}
public static Long getSingleParameterLong(Map map, String name) {
String value = getSingleParameter(map, name);
if (value != null && value.length() > 0) {
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
logger.warn("bad parameter " + name + " [" + value + "]", e);
}
}
return null;
}
public static boolean getSingleParameterBoolean(Map map, String name) {
String value = getSingleParameter(map, name);
if (value == null) return false;
return "true".equalsIgnoreCase(value.trim());
}
public static String getSingleParameter(Map map, String name) {
Object r = map.get(name);
if (r instanceof Collection) {
Collection c = (Collection) r;
r = c.isEmpty() ? null : c.iterator().next();
} else if (r instanceof String[]) {
r = ((String[]) r).length == 0 ? null : ((String[]) r)[0];
}
return r == null ? null : String.valueOf(r);
}
@NotNull
public static List<String> getMultiParameter(Map map, String name) {
Object r = map.get(name);
if (r instanceof Collection) {
Collection c = (Collection) r;
ArrayList<String> result = new ArrayList<String>(c.size());
for (Object o : c) {
if (o != null) result.add(String.valueOf(o));
}
return result;
} else if (r instanceof String[]) {
String[] array = (String[]) r;
return array.length == 0 ? Collections.<String>emptyList() : Arrays.asList(array);
}
return r == null ? Collections.<String>emptyList() : Collections.singletonList(String.valueOf(r));
}
public static List<Long> getMultiParameterLong(Map map, String name) {
return STRING_LONG.arrayList(getMultiParameter(map, name));
}
/**
* Sets a possibly long value (template) as an application property. Because properties may be limited to 255
* characters, this method breaks up long property into several properties each no longer than allowed.
*
* @param properties properties interface
* @param name the name of the property
* @param value the value
*/
public static void setLongProperty(ApplicationProperties properties, String name, String value) {
if (value == null) value = "";
int len = value.length();
int chunk = Math.min(len, MAX_PROPERTY_LENGTH);
properties.setString(name, value.substring(0, chunk));
value = value.substring(chunk);
len -= chunk;
int step = 1;
while (len > 0) {
chunk = Math.min(len, MAX_PROPERTY_LENGTH);
properties.setString(name + "." + (step++), value.substring(0, chunk));
value = value.substring(chunk);
len -= chunk;
}
while (true) {
String n = name + "." + (step++);
String s = properties.getDefaultBackedString(n);
if (s == null || s.length() <= 0) {
break;
}
properties.setString(n, null);
}
}
/**
* Reads a value previously stored in properties using setLongValue
*
* @param properties application propeties
* @param name the name of the property to read
* @return property value or an empty string
*/
public static String getLongProperty(ApplicationProperties properties, String name) {
StringBuilder r = new StringBuilder();
String s = properties.getDefaultBackedString(name);
int step = 1;
while (s != null && s.length() > 0) {
r.append(s);
s = properties.getDefaultBackedString(name + "." + (step++));
}
return r.toString();
}
}