package com.openMap1.mapper.userConverters; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Vector; public class NHS_CDA_TagRuleInterpreter{ // column names in the csv file public static String TAG_RULE_HEADER_ROW = "CDA_Tag,Model_Tag,test,classCode,typeCode,moodCode,Parent_Path,Parent_Test,other_tests"; /* columns in the csv file defining CDA tag name rules */ static int CDA_TAG = 0; static int TEMPLATED_TAG = 1; static int NAME_TEST = 2; static int CLASSCODE = 3; static int TYPECODE = 4; static int MOODCODE = 5; static int PARENT_PATH = 6; static int PARENT_TEST = 7; static int OTHER_TESTS = 8; /** * Try out all possible cda name conversions, to see if any match the rules * @param fullTagName * @param parentPath * @param fixedValues * @param CDATagRules * @return Hashtable of cda tag names which pass the tests */ public static Hashtable<String,String> getCDATagNames(String fullTagName, String parentPath, Vector<String[]> fixedValues, Vector<String[]> CDATagRules) { Hashtable<String,String> cdaNames = new Hashtable<String,String>(); for (int i = 0; i < CDATagRules.size(); i++) { String[] tagRule = CDATagRules.get(i); // test the tag name; "" in the slot tagRule[NAME_TEST] means no test boolean namePasses = someStringTest(fullTagName,tagRule[TEMPLATED_TAG],tagRule[NAME_TEST]); // test the classCode; can be one of several values , separated by '|' boolean classCodePasses = true; String classCode = getFixedValue(fixedValues,"@classCode"); StringTokenizer st = new StringTokenizer(tagRule[CLASSCODE],"|"); if (st.countTokens() > 0) // no test if classCode slot is empty { classCodePasses = false; while (st.hasMoreTokens()) if (st.nextToken().equals(classCode)) classCodePasses = true; } // test the typeCode; can be one of several values , separated by '|' boolean typeCodePasses = true; String typeCode = getFixedValue(fixedValues,"@typeCode"); st = new StringTokenizer(tagRule[TYPECODE],"|"); if (st.countTokens() > 0) // no test if typeCode slot is empty { typeCodePasses = false; while (st.hasMoreTokens()) if (st.nextToken().equals(typeCode)) typeCodePasses = true; } // test the moodCode; can be one of several values , separated by '|' boolean moodCodePasses = true; String moodCode = getFixedValue(fixedValues,"@moodCode"); st = new StringTokenizer(tagRule[MOODCODE],"|"); if (st.countTokens() > 0) // no test if typeCode slot is empty { moodCodePasses = false; while (st.hasMoreTokens()) if (st.nextToken().equals(moodCode)) moodCodePasses = true; } // test the parent path boolean parentNamePasses = someStringTest(parentPath,tagRule[PARENT_PATH],tagRule[PARENT_TEST]); // FIXME; code for other tests looks very limited, compared to the way they are used in the spreadsheet // test other fixed value conditions; AND of tests separated by ';' boolean otherTestPasses = true; st = new StringTokenizer(tagRule[OTHER_TESTS],";"); while (st.hasMoreTokens()) // no test if 'other tests' slot is empty { String otherTest = st.nextToken(); otherTestPasses = otherTestPasses && passesOtherTest(fixedValues,otherTest); } if (namePasses && classCodePasses && typeCodePasses && moodCodePasses && parentNamePasses && otherTestPasses) cdaNames.put(tagRule[CDA_TAG],new Integer(i).toString()); } return cdaNames; } private static boolean someStringTest(String fullTagName, String cdaTagName,String theTest) { boolean namePasses = true; if (theTest.equals("equals")) namePasses = fullTagName.equals(cdaTagName); else if (theTest.equals("!equals")) namePasses = !fullTagName.equals(cdaTagName); else if (theTest.equals("contains")) namePasses = fullTagName.contains(cdaTagName); else if (theTest.equals("!contains")) namePasses = !fullTagName.contains(cdaTagName); else if (theTest.equals("startsWith")) namePasses = fullTagName.startsWith(cdaTagName); else if (theTest.equals("!startsWith")) namePasses = !fullTagName.startsWith(cdaTagName); else if (theTest.equals("endsWith")) namePasses = fullTagName.endsWith(cdaTagName); else if (theTest.equals("!endsWith")) namePasses = !fullTagName.endsWith(cdaTagName); else if (theTest.equals("")) namePasses = true; else trace("Invalid tag name test: '" + theTest + "'"); return namePasses; } /** * * @param fixedValues * @param otherTest * @return */ private static boolean passesOtherTest(Vector<String[]> fixedValues, String otherTest) { boolean passes = false; // only equality tests 'path=value' StringTokenizer st = new StringTokenizer(otherTest,"="); if (st.countTokens() != 2) return false; String path = st.nextToken(); String value = st.nextToken(); // test against all known fixed values at the node for (int i = 0; i < fixedValues.size(); i++) { String[] fv =fixedValues.get(i); if ((fv[0].equals(path)) && (fv[1].equals(value))) passes = true; } return passes; } /** * * @param fixedValues * @param path * @return */ private static String getFixedValue(Vector<String[]> fixedValues, String path) { String fixedValue= ""; for (int i = 0; i < fixedValues.size(); i++) { String[] fv = fixedValues.get(i); if (fv[0].equals(path)) fixedValue = fv[1]; } return fixedValue; } private static void trace(String s) {System.out.println(s);} }