package com.openMap1.mapper.util; import java.text.Collator; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.Vector; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import com.openMap1.mapper.core.MapperException; import com.openMap1.mapper.core.namespace; /** * A collection of general utilities, all static. * * @author robert * */ public class GenUtil { public static void message(String s) {System.out.println(s);} /** return true if the string s is anywhere in the vector v of strings */ public static boolean inVector(String s, Vector<String> v) { int i; boolean res = false; for (i = 0; i < v.size(); i++) { if (s.equals(v.elementAt(i))) res = true; } return res; } /** * * @param s a string * @param v a Vector of strings * @return the number of occurrences of s in v */ public static int countOccurrences(String s, Vector<String> v) { int count = 0; for (int i = 0; i < v.size(); i++) { if (s.equals(v.elementAt(i))) count++; } return count; } /** check if a string is in an array of strings, checking all elements */ public static boolean inArray(String arg, String[] array) { int i,len; boolean res = false; len = array.length; if (len > 0) for ( i = 0; i < len; i++) {if (arg.equals(array[i])) res = true;} return res; } /** * returns true if s1 contains s2 as a substring anywhere */ public static boolean contains(String s1, String s2) { int offset; boolean res = false; if (s1.length() > s2.length() - 1) for (offset = 0; offset < s1.length() - s2.length() + 1; offset++) if (s1.startsWith(s2,offset)) {res = true;} return res; } /** * change the initial letter of a string to lower case * @param s * @return */ public static String initialLowerCase(String s) { String initial = s.substring(0,1).toLowerCase(); return initial + s.substring(1); } /** * change the initial letter of a string to upper case * @param s * @return */ public static String initialUpperCase(String s) { String initial = s.substring(0,1).toUpperCase(); return initial + s.substring(1); } /* returns true if s1 contains s2 as a substring bounded by spaces or commas*/ public static boolean containsAsWord(String s1, String s2) { Vector<String> words = stripWords(s1); return inVector(s2,words); } /** from a string s, strip out words separated by spaces or commas or new lines. */ public static Vector<String> stripWords(String s) { String sTemp; // disposable copy String word; char c; char singleQuote = '\''; char newLine = '\n'; char returnChar = '\r'; Vector<String> res = new Vector<String>(); sTemp = s.substring(0); // make a straight copy of s while (sTemp.length() > 0) { c = sTemp.charAt(0); if ((c == ' ')|(c == ',')|(c == newLine)|(c == returnChar)) { sTemp = sTemp.substring(1); // strip off the first space } else if ((c == singleQuote)|(c == '"')) { word = stringBetween(sTemp,c); // string between quotes sTemp = sTemp.substring(word.length()+2); //strip off string and quotes res.addElement(word); } else { word = firstWord(sTemp); sTemp = sTemp.substring(word.length()); // strip off word res.addElement(word); } } return res; } /* the first character of s is c. Find the string between that and the next occurrence of c, or the end of s. */ private static String stringBetween(String s, char c) { int i; char cp; String res = s.substring(1); // in case no repeat of c is found boolean found = false; // no repeat of c found yet for (i = 1; i < s.length(); i++) // don't look for c in 1st char { cp = s.charAt(i); if ((!found) && (c == cp)) // first repeat of c only {found = true; res = s.substring(1,i);} } return res; } /* return the position of the first occurrence of character c in string s, or -1 if it does not occur.*/ public static int firstOfChar(char c, String s) { int res = -1; boolean found = false; for (int i = 0; i < s.length(); i++) if (!found) if (s.charAt(i) == c) { res = i; found = true; } return res; } /** find the first word in s before any space or comma or new line. The first character of s must not be a space or comma. */ private static String firstWord(String s) { int i; char c; char newLine = '\n'; char returnChar = '\r'; String res = s; // in case no blank is found boolean found = false; // no blank found yet for (i = 1; i < s.length(); i++) // don't look for blank in 1st char { c = s.charAt(i); if ((!found) && ((c == ' ')|(c == ',')|(c == newLine)|(c == returnChar))) // first blank or comma or newline only {found = true; res = s.substring(0,i);} } return res; } /** * Called on catching some Exception that was really expected never to happen. * Writes the exception message, then throws a null pointer Exception. * @param ex the exception * @param methodName method where the exception was caught. */ public static void surprise(Exception ex, String methodName) { System.out.println("Surprise Exception in method '" + methodName + "': " + ex.getMessage()); for (int i = 0; i < ex.getStackTrace().length; i++) System.out.println(ex.getStackTrace()[i].toString()); } /** * replace both the two line break characters by spaces * @param s * @return */ public static String replaceLineBreaksBySpaces(String s) { char space = ' '; char[] replaced = new char[s.length()]; for (int i = 0; i < s.length();i++) { char c = s.charAt(i); if (c==13) replaced[i] = space; else if (c==10) replaced[i] = space; else replaced[i] = c; } String ss = new String(replaced); return ss; } //---------------------------------------------------------------------------------------------------------- // default MDL namespaces //---------------------------------------------------------------------------------------------------------- private static String meNamespaceURI = "http://www/myCo.com/dModel.daml"; private static String meNamespacePrefix = "me"; /** * default MDL namespace for MDL mapping files, given by: * <p> * prefix = "me"; URI = "http://www/myCo.com/dModel.daml" * * @return namespace */ public static namespace defaultMDLNamespace() {return new namespace(meNamespacePrefix,meNamespaceURI);} /** * MDL documents typically start with: * <p> * <schema-adjunct target="http://www/myCo.com/mySchema.xsd" xmlns:me="http://www/myCo.com/dModel.daml"> * <p> * This string defines the 'target' attribute. * * @return String */ public static String MDLTargetNamespaceURI() {return ("http://www/myCo.com/mySchema.xsd");} /** * convert a sequence of words into 'java-like' form - * remove the gaps between words * and make the initial letter of all words except the first upper case. */ public static String gaplessForm(String name) { int i; char[] next = new char[1]; boolean gap = false; String result = ""; String inc; for (i = 0; i < name.length(); i++) { if (name.charAt(i) == ' ') {gap = true;} else { next[0] = name.charAt(i); inc = new String(next); if (gap) {inc = inc.toUpperCase();} gap = false; result = result + inc; } } return result; } // concatenate the strings in a Vector, separated by a separator string public static String concatenate(Vector<String> v, String separator) { String res = ""; for (int i = 0; i < v.size(); i++) { res = res + v.elementAt(i); if (i < v.size() - 1) res = res + separator; } return res; } // true if a CM link can lead at most to one element public static boolean uniqueLink(String CMLink) {return (!((contains(CMLink,"[1:*]"))| // one or more (contains(CMLink,"li"))| // list (contains(CMLink,"[0:*]"))));} // zero or more // true if a CM link implies an element is optional public static boolean optional(String CMLink) {return ((contains(CMLink,"[0:1]"))| // optional (contains(CMLink,"chc"))| // choice (contains(CMLink,"[0:*]")));} // zero or more // return a single String from a Vector of Strings, spaced by " " public static String singleString(Vector<String> strings) { String single = ""; for (int i = 0; i < strings.size(); i++) { if (i > 0) single = single + " "; single = single + strings.elementAt(i); } return single; } /** * * @param stringTable * @return a single string of the keys speparated by spaces */ public static String singleKeyString(Hashtable<String,?> stringTable) { String single = ""; for (Enumeration<String> en = stringTable.keys(); en.hasMoreElements();) single = single + en.nextElement() + " "; return single; } //--------------------------------------------------------------------------------- // Vector copying methods //--------------------------------------------------------------------------------- public static Vector<String> vStringCopy(Vector<String> v) { Vector<String> res = new Vector<String>(); for (Iterator<String> it = v.iterator();it.hasNext();) res.add(it.next()); return res; } //--------------------------------------------------------------------------------- // parsing lines of csv files //--------------------------------------------------------------------------------- /** * convert a line of a csv file into a Vector of Strings. * The components of the Vector are separated by comma in the line, * and may be expressions in double quotes (containing commas which are not treated as separators) * @param line line of a csv file * @return the parts of the line */ public static Vector<String> parseCSVLine(String line) throws MapperException { Vector<String> parsedLine = new Vector<String>(); // for storing the contents of double quotes, which may contain commas Hashtable<String,String> quoteContents = new Hashtable<String,String>(); // the keys used to store contents of double quotes are unique (overkill - they cannot be confused with real text) String uniquePrefix = "£$_"; // pull out and store the contents of double quotes StringTokenizer sQuote = new StringTokenizer(line,"\"",true); String converted = ""; int suffix = 0; boolean inDoubleQuotes = false; while (sQuote.hasMoreTokens()) { String next = sQuote.nextToken(); // deal with double quote marks if (next.equals("\"")) { // two double quotes in succession; store an empty string with a key if (inDoubleQuotes) { String key = uniquePrefix + suffix; suffix++; quoteContents.put(key,""); converted = converted + key; } inDoubleQuotes = !inDoubleQuotes; // update state in/out of quotes converted = converted + "\""; // retain the quote marks } // a non-empty string inside double quotes; save it by key and consume the next double quote else if (inDoubleQuotes) { // save the string by key String key = uniquePrefix + suffix; suffix++; quoteContents.put(key, next); converted = converted + key; // consume the following double quote mark sQuote.nextToken(); inDoubleQuotes = false; converted = converted + "\""; // retain the final quote mark } // a non-empty string not in double quotes (may contain separator commas) else if (!inDoubleQuotes) { converted = converted + next; } } /* must retain commas for the case when two commas are separated by nothing * If there are N columns, there should be (N-1) comma separators. */ StringTokenizer sComma = new StringTokenizer(converted,",", true); int col = 0; String value = ""; while (sComma.hasMoreTokens()) { value = sComma.nextToken(); // encountered an initial comma, or a comma after a comma; interpret the value as empty if (value.equals(",")) { parsedLine.add(""); col++; } // encountered a non-empty value; consume the next comma after it, and check if the value is in quotes else { // consume the next comma, if there is one String comma = ","; if (sComma.hasMoreTokens()) comma = sComma.nextToken(); if (!comma.equals(",")) throw new MapperException("'" + comma + "' is not a ',' at position " + col + " in " + line); // deal with keys for values, in double quotes if ((value.startsWith("\"")) && (value.endsWith("\""))) { value = value.substring(1,value.length() - 1); // strip off quotes from the key if (value.startsWith(uniquePrefix)) // now the value should be one of the keys to quoteContents { String contents = quoteContents.get(value); if (contents == null) throw new MapperException("Cannot find stored value at position " + col + " of line " + line + " by key '" + value + "' in converted line '" + converted + "'" ); parsedLine.add(contents); col++; } else throw new MapperException("Unexpected form of key '" + value + "' at position " + col + " of line " + line); } // deal with unquoted values between commas else { parsedLine.add(value); col++; } } } // a final ',' implies an empty value after the comma, which was not added in the loop above if (converted.endsWith(",")) parsedLine.add(""); return parsedLine; } //--------------------------------------------------------------------------------- // memory management //--------------------------------------------------------------------------------- public static void writeMemory() { Runtime rt = Runtime.getRuntime(); System.out.println("Total " + rt.totalMemory() + "\tMax " + rt.maxMemory() + "\tFree " + rt.freeMemory()); } //--------------------------------------------------------------------------------- // sorting strings //--------------------------------------------------------------------------------- public static Iterator<String> sortedStringKeys(Hashtable<String,?> table) { Collection<String> coll = new TreeSet<String>(Collator.getInstance()); for (Enumeration<String> en = table.keys();en.hasMoreElements();) coll.add(en.nextElement()); return coll.iterator(); } //--------------------------------------------------------------------------------------------- // user messages - copied from WorkBenchUtil //---------------------------------------------------------------------------------------------- /** * show an informative message with an OK button to continue * @param title * @param message */ public static void showMessage(String title, String message) { MessageDialog.openInformation( getShell(), title, message); } /** * @return a shell foe messages and dialogues */ public static Shell getShell() { return PlatformUI.getWorkbench().getWorkbenchWindows()[0].getShell(); } }