/* * Copyright 2013 * * 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 org.openntf.domino.utils; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.io.Serializable; import java.math.BigInteger; import java.nio.ByteBuffer; import java.security.AccessControlException; import java.security.AccessController; import java.security.MessageDigest; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Formatter; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import org.openntf.arpa.NamePartsMap; import org.openntf.domino.DateTime; import org.openntf.domino.ExceptionDetails; import org.openntf.domino.Item; import org.openntf.domino.Name; import org.openntf.domino.Session; import org.openntf.domino.WrapperFactory; import org.openntf.domino.exceptions.InvalidNotesUrlException; import org.openntf.domino.exceptions.OpenNTFNotesException; import org.openntf.domino.ext.Name.NamePartKey; import org.openntf.domino.logging.LogUtils; import org.openntf.domino.utils.Factory.SessionType; import com.ibm.icu.util.Calendar; import com.ibm.icu.util.ULocale; /** * The Enum DominoUtils. */ public enum DominoUtils { ; // private static ConcurrentHashMap CHM = null; // private static ReentrantLock RL = null; // private static ClassLoader defaultLoader = null; // // public static void TEMP_SET_DEFAULT_CLASSLOADER(final ClassLoader loader) { // defaultLoader = loader; // } public static final String VIEWNAME_VIM_PEOPLE_AND_GROUPS = "($VIMPeopleAndGroups)"; public static final String VIEWNAME_VIM_GROUPS = "($VIMGroups)"; public static final int LESS_THAN = -1; public static final int EQUAL = 0; public static final int GREATER_THAN = 1; protected static AtomicInteger CLASS_ERROR_COUNT = new AtomicInteger(0); /** The Constant log_. */ private final static Logger log_ = Logger.getLogger("org.openntf.domino"); /** The Constant logBackup_. */ private final static Logger logBackup_ = Logger.getLogger("com.ibm.xsp.domino"); public static Class<?> getClass(final CharSequence className) { Class<?> result = null; String pname = null; String sname = null; Class<?> pclass = null; String cname = className.toString(); if (cname.startsWith("[L")) { cname = cname.substring(2); } if (cname.endsWith(";")) { cname = cname.substring(0, cname.length() - 1); } try { int pos = cname.indexOf('$'); if (pos > -1) { pname = cname.substring(0, pos); sname = cname.substring(pos + 1); pclass = Class.forName(pname); for (Class<?> curClass : pclass.getDeclaredClasses()) { if (curClass.getSimpleName().equals(sname)) { // Factory.println("FOUND! inner class " + curClass.getSimpleName()); result = curClass; } } if (result == null) { // Factory.println("Failed to default load a class called " + cname + " by parsing to " + pname + " and " + sname // + ". The pname resolved to " + (pclass == null ? "null" : pclass.getName())); } } else { result = Class.forName(className.toString()); } } catch (Throwable t) { // if (cname.contains("$")) { // Factory.println("Failed to default load a class called " + cname + " by parsing to " + pname + " and " + sname // + ". The pname resolved to " + (pclass == null ? "null" : pclass.getName())); // } // ClassLoader cl = Thread.currentThread().getContextClassLoader(); // Factory.println("Initial attempt to find " + className.toString() + " using a class loader of type " + cl.getClass().getName() // + " (" + System.identityHashCode(cl) + ") failed."); } if (result == null) { // Factory.println("TEMP DEBUG Default failed so therefore we're trying privileged versions..."); try { result = AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() { @Override public Class<?> run() throws Exception { Class<?> result = null; ClassLoader cl = Thread.currentThread().getContextClassLoader(); String pname = null; String sname = null; String cname = className.toString(); Class<?> pclass = null; try { if (cname.startsWith("[L")) { cname = cname.substring(2); } int pos = cname.indexOf('$'); if (pos > -1) { pname = cname.substring(0, pos); sname = cname.substring(pos + 1); pclass = Class.forName(pname, false, cl); for (Class<?> curClass : pclass.getDeclaredClasses()) { if (curClass.getSimpleName().equals(sname)) { result = curClass; } } } else { pname = cname; result = Class.forName(pname, false, cl); } } catch (java.lang.ClassNotFoundException e) { try { if (cname.contains("$")) { // Factory.println("Failed to contextClassLoader load a class called " + cname + " by parsing to " + pname // + " and " + sname + ". The pname resolved to " + (pclass == null ? "null" : pclass.getName())); } cl = DominoUtils.class.getClassLoader(); pclass = cl.loadClass(pname); if (sname != null) { for (Class<?> curClass : pclass.getDeclaredClasses()) { if (curClass.getSimpleName().equals(sname)) { result = curClass; } } } else { result = pclass; } } catch (Exception e1) { if (cname.contains("$")) { // Factory.println("Failed to DominoUtils.getClassLoader() load a class called " + cname // + " by parsing to " + pname + " and " + sname + ". The pname resolved to " // + (pclass == null ? "null" : pclass.getName())); } cl = ClassLoader.getSystemClassLoader(); try { pclass = cl.loadClass(pname); if (sname != null) { for (Class<?> curClass : pclass.getDeclaredClasses()) { if (curClass.getSimpleName().equals(sname)) { result = curClass; } } } else { result = pclass; } } catch (Exception e2) { // e2.printStackTrace(); // DominoUtils.handleException(e2); // Factory.println("STILL couldn't get class " + pname + " using system classloader " // + cl.getClass().getName()); } } } catch (Throwable t) { t.printStackTrace(); DominoUtils.handleException(t); } return result; } }); } catch (AccessControlException e) { e.printStackTrace(); DominoUtils.handleException(e); } catch (PrivilegedActionException e) { e.printStackTrace(); DominoUtils.handleException(e); } } if (result == null) { int count = DominoUtils.CLASS_ERROR_COUNT.incrementAndGet(); log_.log(Level.WARNING, "Unable to resolve class " + className + " Please check logs for more details. Incident " + count); // if (count > 50) { // Thread.currentThread().interrupt(); // } } return result; } private static ThreadLocal<Boolean> bubbleExceptions_ = new ThreadLocal<Boolean>() { @Override protected Boolean initialValue() { // System.out.println("INIT"); return Boolean.valueOf(Factory.getThreadConfig().bubbleExceptions); } }; public static Boolean getBubbleExceptions() { Boolean ret = bubbleExceptions_.get(); if (ret == null) { ret = Boolean.valueOf(Factory.getThreadConfig().bubbleExceptions); bubbleExceptions_.set(ret); } return ret; } public static void setBubbleExceptions(final Boolean value) { bubbleExceptions_.set(value); } public static class LoaderObjectInputStream extends ObjectInputStream { // private final ClassLoader loader_; public LoaderObjectInputStream(final InputStream in) throws IOException { super(in); // loader_ = null; } // public LoaderObjectInputStream(final ClassLoader classLoader, final InputStream in) throws IOException { // super(in); // loader_ = classLoader; // } @Override protected Class<?> resolveClass(final ObjectStreamClass desc) throws IOException, ClassNotFoundException { String name = desc.getName(); Class<?> result = null; try { result = DominoUtils.getClass(name); } catch (Exception e) { result = super.resolveClass(desc); } if (result == null) { result = super.resolveClass(desc); } return result; } @Override protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { // TODO Auto-generated method stub return super.readClassDescriptor(); } } /** * Checksum. * * @param bytes * the bytes * @param alg * the alg * @return the string */ public static String checksum(final byte[] bytes, final String alg) { String hashed = ""; byte[] defaultBytes = bytes; try { MessageDigest algorithm = MessageDigest.getInstance(alg); algorithm.reset(); algorithm.update(defaultBytes); byte[] messageDigest = algorithm.digest(); BigInteger bi = new BigInteger(1, messageDigest); // StringBuffer hexString = new StringBuffer(); // for (byte element : messageDigest) { // String hex = Integer.toHexString(0xFF & element); // if (hex.length() == 1) { // hexString.append('0'); // } // hexString.append(hex); // } hashed = bi.toString(16); } catch (Throwable t) { DominoUtils.handleException(t); } return hashed; } /** * Checks if is number. * * @param value * the value * @return true, if is number */ public static boolean isNumber(final CharSequence value) { boolean seenDot = false; boolean seenExp = false; boolean justSeenExp = false; boolean seenDigit = false; for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); if (c >= '0' && c <= '9') { seenDigit = true; continue; } if ((c == '-' || c == '+') && (i == 0 || justSeenExp)) { continue; } if (c == '.' && !seenDot) { seenDot = true; continue; } justSeenExp = false; if ((c == 'e' || c == 'E') && !seenExp) { seenExp = true; justSeenExp = true; continue; } return false; } if (!seenDigit) { return false; } try { Double.parseDouble(value.toString()); return true; } catch (NumberFormatException e) { return false; } } /** * Checksum. * * @param object * the object * @param algorithm * the algorithm * @return the string */ public static String checksum(final Serializable object, final String algorithm) { String result = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(baos); out.writeObject(object); result = DominoUtils.checksum(baos.toByteArray(), algorithm); out.close(); } catch (Throwable t) { DominoUtils.handleException(t); } return result; } /** * Handle exception. * * @param t * the t * @return the throwable */ public static Throwable handleException(final Throwable t) { return (handleException(t, null, null)); } public static Throwable handleException(final Throwable t, final ExceptionDetails hed) { return handleException(t, hed, null); } public static Throwable handleException(final Throwable t, final String details) { return handleException(t, null, details); } public static Throwable handleException(final Throwable t, final ExceptionDetails hed, final String details) { if (t instanceof OpenNTFNotesException) { OpenNTFNotesException ne = (OpenNTFNotesException) t; ne.addExceptionDetails(hed); throw ne; } if (getBubbleExceptions()) { throw new OpenNTFNotesException(details, t, hed); } try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { if (log_.getLevel() == null) { LogUtils.loadLoggerConfig(false, ""); } if (log_.getLevel() == null) { log_.setLevel(Level.WARNING); } return null; } }); AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { if (LogUtils.hasAccessException(log_)) { logBackup_.log(Level.SEVERE, t.getLocalizedMessage(), t); } else { log_.log(Level.WARNING, t.getLocalizedMessage(), t); } return null; } }); } catch (Throwable e) { e.printStackTrace(); } return t; } /** * Gets the unid from notes url. * * @param notesurl * the notesurl * @return the unid from notes url */ public static String getUnidFromNotesUrl(final CharSequence notesurl) { String result = null; String trimmed = notesurl.toString().toLowerCase().trim(); if (trimmed.startsWith("notes://")) { int arg = trimmed.lastIndexOf('?'); if (arg == -1) { // there's no ? so we'll just start from the end String chk = trimmed.substring(trimmed.length() - 32, trimmed.length()); if (isUnid(chk)) { result = chk; } else { System.out.println("Not a unid. We got " + chk); } } else { String chk = trimmed.substring(0, arg); chk = chk.substring(chk.length() - 32, chk.length()); // String chk = trimmed.substring(trimmed.length() - 32 - (arg + 1), trimmed.length() - (arg + 1)); if (isUnid(chk)) { result = chk; } else { System.out.println("Not a unid. We got " + chk); } } } else { throw new InvalidNotesUrlException(notesurl.toString()); } return result; } /** * Incinerate. * * @param args * the args * @deprecated you should recycle objects by passing them to the WrapperFactory */ @SuppressWarnings({ "unchecked", "rawtypes" }) @Deprecated public static void incinerate(final Object... args) { for (Object o : args) { if (o != null) { if (o instanceof lotus.domino.Base) { // try { // ((Base) o).recycle(); // } catch (Throwable t) { // // who cares? // } WrapperFactory wf = Factory.getWrapperFactory(); wf.recycle((lotus.domino.Base) o); } else if (o instanceof Map) { Set<Map.Entry> entries = ((Map) o).entrySet(); for (Map.Entry<?, ?> entry : entries) { incinerate(entry.getKey(), entry.getValue()); } } else if (o instanceof Collection) { Iterator i = ((Collection) o).iterator(); while (i.hasNext()) { Object obj = i.next(); incinerate(obj); } } else if (o.getClass().isArray()) { try { Object[] objs = (Object[]) o; for (Object ao : objs) { incinerate(ao); } } catch (Throwable t) { // who cares? } } } } } public static boolean isHierarchicalName(final CharSequence name) { return (Strings.isBlankString(name.toString())) ? false : Names.IS_HIERARCHICAL_MATCH.matcher(name).find(); } public static void parseNamesPartMap(final CharSequence name, final NamePartsMap map) { if (isHierarchicalName(name)) { Matcher m = Names.CN_MATCH.matcher(name); if (m.find()) { int start = m.start() + 3; int end = m.end(); if (start < end) { map.put(NamePartKey.Common, name.subSequence(start, end).toString()); } else { map.put(NamePartKey.Common, name.toString()); } } m = Names.O_MATCH.matcher(name); if (m.find()) { int start = m.start() + 2; int end = m.end(); if (start < end) { map.put(NamePartKey.Organization, name.subSequence(start, end).toString()); } else { map.put(NamePartKey.Organization, name.toString()); } } m = Names.C_MATCH.matcher(name); if (m.find()) { int start = m.start() + 2; int end = m.end(); if (start < end) { map.put(NamePartKey.Country, name.subSequence(start, end).toString()); } else { map.put(NamePartKey.Country, name.toString()); } } m = Names.OU_MATCH.matcher(name); int i = 0; while (m.find()) { int start = m.start() + 3; int end = m.end(); if (start < end) { if (i == 0) map.put(NamePartKey.OrgUnit1, name.subSequence(start, end).toString()); if (i == 1) map.put(NamePartKey.OrgUnit2, name.subSequence(start, end).toString()); if (i == 2) map.put(NamePartKey.OrgUnit3, name.subSequence(start, end).toString()); if (i == 3) map.put(NamePartKey.OrgUnit4, name.subSequence(start, end).toString()); } } } } public static String toAbbreviatedName(final CharSequence name) { if (isHierarchicalName(name)) { StringBuilder builder = new StringBuilder(); boolean isFirst = true; String cn = toCommonName(name); if (cn.length() > 0) { isFirst = false; builder.append(cn); } String ouString = toOUString(name); if (ouString.length() > 0) { if (!isFirst) { builder.append('/'); } isFirst = false; builder.append(toOUString(name)); } // String[] ous = toOU(name); // if (ous.length > 0) { // for (String ou : ous) { // if (ou.length() > 0) { // if (!isFirst) // builder.append('/'); // isFirst = false; // builder.append(ou); // } // } // } String o = toOrgName(name); if (o.length() > 0) { if (!isFirst) builder.append('/'); isFirst = false; builder.append(o); } String c = toCountry(name); if (c.length() > 0) { if (!isFirst) builder.append('/'); isFirst = false; builder.append(c); } return builder.toString(); } else { return name.toString(); } } public static String toCommonName(final CharSequence name) { if (isHierarchicalName(name)) { Matcher m = Names.CN_MATCH.matcher(name); if (m.find()) { int start = m.start() + 3; int end = m.end(); if (start < end) { return name.subSequence(start, end).toString(); } else { return name.toString(); } } else { return ""; } } else { return name.toString(); } } public static String toOrgName(final CharSequence name) { if (isHierarchicalName(name)) { Matcher m = Names.O_MATCH.matcher(name); if (m.find()) { int start = m.start() + 2; int end = m.end(); if (start < end) { return name.subSequence(start, end).toString(); } else { return name.toString(); } } else { return ""; } } else { return name.toString(); } } public static String toOUString(final CharSequence name) { if (isHierarchicalName(name)) { Matcher m = Names.OU_MATCH.matcher(name); StringBuilder builder = new StringBuilder(); int i = 0; while (m.find()) { int start = m.start() + 3; int end = m.end(); if (start < end) { if (i > 0) { builder.append('/'); } builder.append(name.subSequence(start, end)); i++; } } if (i == 0) { return ""; } else { return builder.toString(); } } else { return ""; } } public static String[] toOU(final CharSequence name) { if (isHierarchicalName(name)) { Matcher m = Names.OU_MATCH.matcher(name); String[] ous = new String[4]; //maximum number of OUs according to spec int i = 0; while (m.find()) { int start = m.start() + 3; int end = m.end(); if (start < end) { ous[i++] = name.subSequence(start, end).toString(); } } if (i == 0) { return new String[0]; } else { String[] result = new String[i]; System.arraycopy(ous, 0, result, 0, i); return result; } } else { return new String[0]; } } public static String toCountry(final CharSequence name) { if (isHierarchicalName(name)) { Matcher m = Names.C_MATCH.matcher(name); if (m.find()) { int start = m.start() + 2; int end = m.end(); if (start < end) { return name.subSequence(start, end).toString(); } else { return name.toString(); } } else { return ""; } } else { return name.toString(); } } public static String toNameType(final CharSequence name, final Name.NameType type) { switch (type) { case COMMON: return toCommonName(name); case ABBREVIATED: return toAbbreviatedName(name); case CANONICAL: return name.toString(); case ORG: return toOrgName(name); case ORGUNIT: return toOUString(name); case COUNTRY: return toCountry(name); } return name.toString(); } public static Map<String, String> mapNames(final Collection<String> names, final Name.NameType keyType, final Name.NameType valueType) { if (names != null) { Map<String, String> result = new LinkedHashMap<String, String>(); for (String name : names) { String key = toNameType(name, keyType); String value = toNameType(name, valueType); result.put(key, value); } return result; } else { return null; } } public static List<String> toSelectionList(final Collection<String> names, final Name.NameType firstType, final Name.NameType secondType) { return toSelectionList(names, firstType, secondType, "|"); } public static List<String> toSelectionList(final Collection<String> names, final Name.NameType firstType, final Name.NameType secondType, final CharSequence separator) { if (names != null) { List<String> result = new LinkedList<String>(); for (String name : names) { String key = toNameType(name, firstType); String value = toNameType(name, secondType); result.add(key + separator + value); } return result; } else { return null; } } /** * Checks if is hex. * * @param value * the value * @return true, if is hex */ public static boolean isHex(final CharSequence value) { if (value == null) return false; String chk = value.toString().trim().toLowerCase(); for (int i = 0; i < chk.length(); i++) { char c = chk.charAt(i); boolean isHexDigit = Character.isDigit(c) || Character.isWhitespace(c) || c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f'; if (!isHexDigit) { return false; } } return true; } /** * Checks if is unid. * * @param value * the value * @return true, if is 32-character hexadecimal sequence */ public static boolean isUnid(final CharSequence value) { if (value.length() != 32) return false; return DominoUtils.isHex(value); } /** * Checks if is replica id. * * @param value * the value * @return true, if is 16-character hexadecimal sequence */ public static boolean isReplicaId(final CharSequence value) { if (value.length() != 16) return false; return DominoUtils.isHex(value); } /** * Checks if is metaversal id. * * @param value * the value * @return true, if is 48-character hexadecimal sequence */ public static boolean isMetaversalId(final CharSequence value) { if (value.length() != 48) return false; return DominoUtils.isHex(value); } /** * Md5. * * @param object * the Serializable object * @return the string representing the MD5 hash value of the serialized version of the object */ public static String md5(final Serializable object) { return DominoUtils.checksum(object, "MD5"); } /** * To unid. * * @param value * the value * @return a 32-character hexadecimal string that can be used as a UNID, uniquely and deterministically based on the value argument */ public static String toUnid(final Serializable value) { if (value instanceof CharSequence && DominoUtils.isUnid((CharSequence) value)) return value.toString(); String hash = DominoUtils.md5(value); while (hash.length() < 32) { hash = "0" + hash; } return hash.toUpperCase(); } public static byte[] toByteArray(final CharSequence hexString) { if (hexString.length() % 2 != 0) throw new IllegalArgumentException("Only hex strings with an even number of digits can be converted"); int arrLength = hexString.length() >> 1; byte buf[] = new byte[arrLength]; for (int ii = 0; ii < arrLength; ii++) { int index = ii << 1; CharSequence l_digit = hexString.subSequence(index, index + 2); buf[ii] = (byte) Integer.parseInt(l_digit.toString(), 16); } return buf; } public static String toHex(final byte[] bytes) { Formatter formatter = new Formatter(); for (byte b : bytes) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } public static Integer toInteger(final byte[] bytes) { //FIXME NTF This feels wrong. Should we pad the byte array? Am I being pedantic? if (bytes.length == 1) { return Byte.valueOf(bytes[0]).intValue(); } else if (bytes.length == 2) { ByteBuffer wrapped = ByteBuffer.wrap(bytes); short s = wrapped.getShort(); return Short.valueOf(s).intValue(); } else if (bytes.length == 4) { ByteBuffer wrapped = ByteBuffer.wrap(bytes); int i = wrapped.getInt(); return i; } else { throw new IllegalArgumentException("Cannot convert a byte array of length " + bytes.length + " to Integer"); } } /** * To java calendar safe. * * @param dt * the dt * @return the calendar */ public static Calendar toJavaCalendarSafe(final lotus.domino.DateTime dt) { Date d = DominoUtils.toJavaDateSafe(dt); Calendar c = Calendar.getInstance(ULocale.getDefault()); c.setTime(d); return c; } /** * To java date. * * @param l * the l * @return the date */ public static Date toJavaDate(final long l) { Date result = new Date(); result.setTime(l); return result; } /** * To java date. * * @param ls * the ls * @return the collection */ public static Collection<Date> toJavaDate(final long[] ls) { Collection<Date> result = new ArrayList<Date>(); for (long l : ls) { result.add(DominoUtils.toJavaDate(l)); } return result; } /** * To java date safe. * * @param dt * the dt * @return the date */ public static Date toJavaDateSafe(final lotus.domino.DateTime dt) { Date date = null; if (dt != null) { if (dt instanceof org.openntf.domino.DateTime) { date = ((org.openntf.domino.DateTime) dt).toJavaDate(); // no need to recycle 'cause it's not toxic } else { try { date = dt.toJavaDate(); } catch (Throwable t) { t.printStackTrace(); } finally { DominoUtils.incinerate(dt); } } } return date; } /** * Gets the domino ini var. * * @param propertyName * String property to retrieve from notes.ini * @param defaultValue * String default to use if property is not found * @return String return value from the notes.ini */ public static String getDominoIniVar(final String propertyName, final String defaultValue) { String newVal = Factory.getSession(SessionType.CURRENT).getEnvironmentString(propertyName, true); if (!"".equals(newVal)) { return newVal; } else { return defaultValue; } } /** * Gets properties file and returns as an InputStream. * * @param fileType * int passed to switch statement. <br/> * 1 -> name of a properties file in this package<br/> * 2 -> literal path of a properties file<br/> * 3 -> relative path of a properties file, relative to Domino <data> directory * @param fileLoc * String filepath location of properties file * @return InputStream (or BufferedInputStream) of properties file content */ public static InputStream getDominoProps(final int fileType, final String fileLoc) { InputStream returnStream = null; InputStream is; try { switch (fileType) { case 1: // Properties file in this package returnStream = DominoUtils.class.getResourceAsStream(fileLoc); break; case 2: // File in file system at literal path is = new FileInputStream(fileLoc); returnStream = new BufferedInputStream(is); break; case 3: // File in file system relative to data directory String dirPath = getDominoIniVar("Directory", ""); is = new FileInputStream(dirPath + "/" + fileLoc); returnStream = new BufferedInputStream(is); break; // TODO Need to work out how to get from properties file in NSF } return returnStream; } catch (Throwable e) { handleException(e); return returnStream; } } public static Item itemFromCalendar(final Item item, final Calendar cal) { DateTime dt = item.getAncestorSession().createDateTime(cal); item.setDateTimeValue(dt); DominoUtils.incinerate(dt); return item; } public static Item itemFromCalendarAppend(final Item item, final Calendar cal) { Session sess = item.getAncestorSession(); DateTime dt = sess.createDateTime(cal); Vector<DateTime> v = item.getValueDateTimeArray(); v.add(dt); item.setValues(v); sess.getFactory().recycle(dt); return item; } public static Item itemFromDate(final Item item, final Date cal) { Session sess = item.getAncestorSession(); DateTime dt = sess.createDateTime(cal); item.setDateTimeValue(dt); sess.getFactory().recycle(dt); return item; } public static Item itemFromDateAppend(final Item item, final Date cal) { Session sess = item.getAncestorSession(); DateTime dt = sess.createDateTime(cal); Vector<DateTime> v = item.getValueDateTimeArray(); v.add(dt); item.setValues(v); sess.getFactory().recycle(dt); return item; } public static Calendar itemToCalendar(final Item item) { DateTime dt = item.getDateTimeValue(); if (dt != null) { return DominoUtils.toJavaCalendarSafe(dt); } else { return null; } } public static Date itemToDate(final Item item) { DateTime dt = item.getDateTimeValue(); if (dt != null) { return DominoUtils.toJavaDateSafe(dt); } else { return null; } } public static String escapeForFormulaString(final String value) { // I wonder if this is sufficient escaping return value.replace("{", "\\{").replace("}", "\\}"); } public static boolean isSerializable(final Collection<?> values) { if (values == null) return false; boolean result = true; Iterator<?> it = values.iterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof DateTime) { return false; } if (!(o instanceof Serializable)) { result = false; break; } } return result; } public static String toNameString(final Name name) { String result = ""; if (!name.isHierarchical()) { result = name.getCommon(); } else { result = name.getCanonical(); } return result; } @SuppressWarnings("rawtypes") public static Collection<Comparable> toComparable(final Collection<?> values) { Collection<Serializable> colls = toSerializable(values); Collection<Comparable> result = new ArrayList<Comparable>(); if (colls != null && !colls.isEmpty()) { for (Serializable ser : colls) { if (ser instanceof Comparable) { result.add((Comparable) ser); } else { log_.info("Unable to convert to Comparable from " + ser.getClass().getName()); } } } return result; } @SuppressWarnings("unchecked") public static Collection<Serializable> toSerializable(final Collection<?> values) { if (DominoUtils.isSerializable(values)) return (Collection<Serializable>) values; Collection<Serializable> result = new ArrayList<Serializable>(); if (values != null && !values.isEmpty()) { Iterator<?> it = values.iterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof DateTime) { Date date = null; DateTime dt = (DateTime) o; date = dt.toJavaDate(); result.add(date); } else if (o instanceof Name) { result.add(DominoUtils.toNameString((Name) o)); } else if (o instanceof String) { result.add((String) o); } else if (o instanceof Number) { result.add((Number) o); } } } return result; } public static String javaBinaryNameToFilePath(final CharSequence binaryName, final String separator) { return binaryName.toString().replace(".", separator) + ".class"; } public static String filePathToJavaBinaryName(final CharSequence filePath, final String separator) { return filePath.subSequence(0, filePath.length() - 6).toString().replace(separator, "."); } }