/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.cg.generator; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openflexo.foundation.cg.GenerationRepository; import org.openflexo.foundation.wkf.node.ActionNode; import org.openflexo.foundation.wkf.node.OperationNode; import org.openflexo.toolbox.ToolBox; /** * Some utilities used in the context of Code Generator * * @author bmangez */ public class GeneratorUtils { public static final String OUTPUT_FILES_ENCODING = "UTF-8"; public static final String CONTENT_TAG = "<_CONTENT_>"; public static final String GEN_IF = "GEN_IF"; public static final String BAD_CHARS_IN_WOD_VALUE_REGEXP = "[ \"\\\\]+"; public static final Pattern BAD_CHARS_IN_WOD_VALUE_PATTERN = Pattern.compile(BAD_CHARS_IN_WOD_VALUE_REGEXP); public static final String JAVA_CHAR_TO_ESCAPE_IN_STRINGS_REG_EXP = "[\"\\\\]"; public static final Pattern JAVA_CHAR_TO_ESCAPE_IN_STRINGS_PATTERN = Pattern.compile(JAVA_CHAR_TO_ESCAPE_IN_STRINGS_REG_EXP); /** * @deprecated use {@link ToolBox} convertStringToJavaString * @param stringToConvert * @return */ @Deprecated public static String convertStringToJavaString(String stringToConvert) { return ToolBox.convertStringToJavaString(stringToConvert); } public static String beforeContentHtml(String html) { if (html == null || html.equals("")) { return ""; } int tagIndex = html.indexOf(CONTENT_TAG); if (tagIndex != -1) { return html.substring(0, tagIndex); } else { return html; } } public static String afterContentHtml(String html) { if (html == null || html.equals("")) { return ""; } int tagIndex = html.indexOf(CONTENT_TAG); if (tagIndex != -1) { return html.substring(tagIndex + CONTENT_TAG.length()); } else { return ""; } } /** * @deprecated use ToolBox.getJavaName(name) * @param name * @return a java name ( starts with a minuscule, and no blanks, dot,..., convert accentuated characters) */ @Deprecated public static String getJavaName(String name) { return ToolBox.getJavaName(name); } public static String getWodValueName(String s) { if (s == null) { return ""; } Matcher m = BAD_CHARS_IN_WOD_VALUE_PATTERN.matcher(s); StringBuffer sb = new StringBuffer(); while (m.find()) { m.appendReplacement(sb, ""); } m.appendTail(sb); return sb.toString(); } /** * Replace ",',\n,\r by blank * * @param comment * @return a String to use in a javascript */ public static String getJavascriptComment(String comment) { if (comment == null) { return null; } return ToolBox.replaceStringByStringInString( "\r", " ", ToolBox.replaceStringByStringInString("\n", " ", ToolBox.replaceStringByStringInString("\"", " ", ToolBox.replaceStringByStringInString("'", " ", comment)))); } public static String getJavascriptComment2(String comment) { if (comment == null) { return null; } return ToolBox.replaceStringByStringInString("\r", " ", ToolBox.replaceStringByStringInString("\n", " ", ToolBox.replaceStringByStringInString("\"", " ", comment))); } public static String evaluateConditions(String value, Map replacement) { if (value == null) { return null; } String condBeginString = "<" + GEN_IF + "("; int condBegin = value.indexOf(condBeginString); if (condBegin != -1) { boolean condition = false; String conditionKey = value.substring(condBegin + condBeginString.length(), value.indexOf(")", condBegin + condBeginString.length())); int contentBegin = condBegin + condBeginString.length() + conditionKey.length() + 2; int contentEnd = value.indexOf("</" + GEN_IF + "(" + conditionKey + ")>"); int condEnd = contentEnd + 2 + GEN_IF.length() + 1 + conditionKey.length() + 2; StringTokenizer stk = new StringTokenizer(conditionKey, "|"); while (stk.hasMoreTokens()) { String orToken = stk.nextToken(); boolean negate = orToken.startsWith("!"); Object conditionValue; if (negate) { conditionValue = replacement.get("<" + orToken.substring(1) + ">"); } else { conditionValue = replacement.get("<" + orToken + ">"); } boolean orCondition = conditionValue != null && !conditionValue.toString().equals(""); if (negate) { orCondition = !orCondition; } if (orCondition) { condition = true; break; } } StringBuffer clean = new StringBuffer(value.length()); String before = value.substring(0, condBegin); // 1. before condition // New line before <GEN_IF is removed if (before.endsWith("\n\r")) { before = before.substring(0, before.length() - 2); } else if (before.endsWith("\r\n")) { before = before.substring(0, before.length() - 2); } else if (before.endsWith("\r")) { before = before.substring(0, before.length() - 1); } else if (before.endsWith("\n")) { before = before.substring(0, before.length() - 1); } clean.append(before); // 2. between condition if (condition) { String content = value.substring(contentBegin, contentEnd); // New line before </GEN_IF is removed if (content.endsWith("\n\r")) { content = content.substring(0, content.length() - 2); } else if (content.endsWith("\r\n")) { content = content.substring(0, content.length() - 2); } else if (content.endsWith("\r")) { content = content.substring(0, content.length() - 1); } else if (content.endsWith("\n")) { content = content.substring(0, content.length() - 1); } clean.append(content); } // 3. after condition clean.append(value.substring(condEnd)); return evaluateConditions(clean.toString(), replacement); } else { return value; } } public static String[] getStringBetweenTags(String string, String tag) { String resp = ""; if (string != null) { String beginTag = "<" + tag + ">"; String endTag = "</" + tag + ">"; int begin = string.indexOf(beginTag); if (begin != -1) { int end = string.indexOf(endTag, begin); if (end != -1) { resp = string.substring(begin + beginTag.length(), end); String before = string.substring(0, begin); if (before.endsWith("\n\r") || before.endsWith("\r\n")) { before = before.substring(0, before.length() - 2); } else if (before.endsWith("\r") || before.endsWith("\n")) { before = before.substring(0, before.length() - 1); } String after = string.substring(end + endTag.length()); if (after.endsWith("\n\r") || after.endsWith("\r\n")) { after = after.substring(0, after.length() - 2); } else if (after.endsWith("\r") || after.endsWith("\n")) { after = after.substring(0, after.length() - 1); } string = before + after; } } } return new String[] { string, resp }; } /** * * Remove the code generator comments. A code generator comment is a line starting with ##. * * @param template * @return the template, with no code generator comments */ public static String removeComments(String template) { int i = template.indexOf("##"); while (i != -1) { int endOfLineN = template.indexOf("\n", i); int endOfLineR = template.indexOf("\r", i); int endOfLine; if (endOfLineN == -1 && endOfLineR == -1) { endOfLine = template.length(); } else if (endOfLineN == -1 && endOfLineR != -1) { endOfLine = endOfLineR; } else if (endOfLineN != -1 && endOfLineR == -1) { endOfLine = endOfLineN; } else { endOfLine = Math.min(endOfLineR, endOfLineN); if (endOfLine + 1 == Math.max(endOfLineR, endOfLineN)) { endOfLine = endOfLine + 1; } } StringBuffer buf = new StringBuffer(template.length()); buf.append(template.substring(0, i)).append(template.substring(endOfLine + 1)); template = buf.toString(); i = template.indexOf("##"); } return template; } /* * @deprecated public static String generateSimpleRepetition(Vector * list,String templateName,Properties replacement){ String * answer = ""; Enumeration en = list.elements(); * while(en.hasMoreElements()){ replacement.put("<ITEM>",en.nextElement()); * answer=answer+generateCode(templateName,replacement); } * return answer; } */ public static File saveToFile(String fileName, String fileCode, File dir, String fileExtention) { try { if (!dir.exists()) { dir.mkdirs(); } } catch (Exception e) { e.printStackTrace(); } FileOutputStream fos = null; try { File dest = new File(dir.getAbsolutePath() + File.separator + getFileName(fileName, fileExtention)); dest.createNewFile(); byte[] b; if (fileCode != null) { b = fileCode.getBytes(OUTPUT_FILES_ENCODING); } else { b = new byte[0]; } fos = new FileOutputStream(dest); fos.write(b); return dest; } catch (Exception e) { e.printStackTrace(); return null; } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static String getFileName(String fileName, String fileExtention) { if (fileExtention != null) { return fileName + "." + fileExtention; } else { return fileName; } } public static String defaultWOO() { return "" + "{\n" + " \"WebObjects Release\" = \"WebObjects 5.0\";\n" + " encoding = NSUTF8StringEncoding;\n" + " variables = {};\n" + "}"; } public static void writeWOComponentFiles(File woComponentDirectory, File javaSrcDirectory, String woComponentName, String javaCode, String apiCode, String htmlCode, String wodCode, String wooCode) { woComponentDirectory.mkdirs(); File woDir = null; if (htmlCode != null || wodCode != null || wooCode != null) { woDir = new File(woComponentDirectory, woComponentName + ".wo"); } if (woDir != null && !woDir.exists()) { woDir.mkdir(); } try { if (javaCode != null) { saveToFile(woComponentName, javaCode, javaSrcDirectory == null ? woComponentDirectory : javaSrcDirectory, "java"); } if (apiCode != null) { saveToFile(woComponentName, apiCode, woComponentDirectory, "api"); } if (htmlCode != null) { saveToFile(woComponentName, htmlCode, woDir, "html"); } if (wodCode != null) { saveToFile(woComponentName, wodCode, woDir, "wod"); } if (wooCode != null) { saveToFile(woComponentName, wooCode, woDir, "woo"); } } catch (Exception e) { e.printStackTrace(); } } public static String stringFromFile(File f) { try { FileInputStream fis = new FileInputStream(f); StringBuffer buf = new StringBuffer(); while (fis.available() > 0) { byte[] b = new byte[fis.available()]; fis.read(b); buf.append(new String(b)); } fis.close(); return buf.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } /** * Returns true if ch matches [A-Za-z] http://www.asciitable.com * * @param ch * @return */ public static boolean isAlpha(char ch) { // returns true if ch matches [A-Za-z] return ch > (char) 64 && ch < (char) 91 || ch > (char) 96 && ch < (char) 123; } // converts the first character of the string to uppercase, or the second // one if the first is not alphabetic (eg an underscore) public static String capitalize(String str) { if (isAlpha(str.charAt(0))) { return str.substring(0, 1).toUpperCase() + str.substring(1); } else { // if starts with '_' for example, capitalize 2nd character return str.charAt(0) + str.substring(1, 2).toUpperCase() + str.substring(2); } } /** * Replace any "." by "_" in the accessor. * * @param accessorValue * @return an accessor name, with no "." */ public static String accessorName(String accessorValue) { return ToolBox.replaceStringByStringInString(".", "_", accessorValue); } public static String dateString(Date timestamp) { if (timestamp == null) { return null; } GregorianCalendar cal = new GregorianCalendar(); cal.setTime(timestamp); int year = cal.get(Calendar.YEAR); int monthIndex = cal.get(Calendar.MONTH); // log("day of week: "+ dayOfWeek); int day = cal.get(Calendar.DAY_OF_MONTH); String dayString = String.valueOf(day); String twoCharsDayString = day > 9 ? String.valueOf(dayString) : "0" + String.valueOf(dayString); String monthString = monthIndex + 1 > 9 ? String.valueOf(monthIndex + 1) : "0" + String.valueOf(monthIndex + 1); String yearString = String.valueOf(year); String fourCharsYearString = year < 1000 ? year < 100 ? year < 10 ? "000" + yearString : "00" + yearString : "0" + yearString : yearString; return twoCharsDayString + "/" + monthString + "/" + fourCharsYearString; } /** * Returns a String with only characters [a-Z] or [0-9] or defaultChar. * * @param string * @param defaultChar * @return a String with only characters [a-Z] or [0-9] or defaultChar. */ public static String stringToRestrictedCase(String string, char defaultChar) { char[] array = string.toCharArray(); char[] newArray = new char[string.length()]; for (int i = 0; i < string.length(); i++) { char c = array[i]; String ch = ("" + c).toLowerCase(); boolean isLower = ("" + c).equals(ch); if (ch.equals("a") || ch.equals("�") || ch.equals("�") || ch.equals("�") || ch.equals("�")) { newArray[i] = isLower ? 'a' : 'A'; } else if (ch.equals("b")) { newArray[i] = isLower ? 'b' : 'B'; } else if (ch.equals("c") || ch.equals("�")) { newArray[i] = isLower ? 'c' : 'C'; } else if (ch.equals("d")) { newArray[i] = isLower ? 'd' : 'D'; } else if (ch.equals("e") || ch.equals("�") || ch.equals("�") || ch.equals("�") || ch.equals("�")) { newArray[i] = isLower ? 'e' : 'E'; } else if (ch.equals("f")) { newArray[i] = isLower ? 'f' : 'F'; } else if (ch.equals("g")) { newArray[i] = isLower ? 'g' : 'G'; } else if (ch.equals("h")) { newArray[i] = isLower ? 'h' : 'H'; } else if (ch.equals("i") || ch.equals("�") || ch.equals("�") || ch.equals("�") || ch.equals("�")) { newArray[i] = isLower ? 'i' : 'I'; } else if (ch.equals("j")) { newArray[i] = isLower ? 'j' : 'J'; } else if (ch.equals("k")) { newArray[i] = isLower ? 'k' : 'K'; } else if (ch.equals("l")) { newArray[i] = isLower ? 'l' : 'L'; } else if (ch.equals("m")) { newArray[i] = isLower ? 'm' : 'M'; } else if (ch.equals("n")) { newArray[i] = isLower ? 'n' : 'N'; } else if (ch.equals("o") || ch.equals("�") || ch.equals("�") || ch.equals("�") || ch.equals("�") || ch.equals("�") || ch.equals("�")) { newArray[i] = isLower ? 'o' : 'O'; } else if (ch.equals("p")) { newArray[i] = isLower ? 'p' : 'P'; } else if (ch.equals("q")) { newArray[i] = isLower ? 'q' : 'Q'; } else if (ch.equals("r")) { newArray[i] = isLower ? 'r' : 'R'; } else if (ch.equals("s")) { newArray[i] = isLower ? 's' : 'S'; } else if (ch.equals("t")) { newArray[i] = isLower ? 't' : 'T'; } else if (ch.equals("u") || ch.equals("�") || ch.equals("�") || ch.equals("�")) { newArray[i] = isLower ? 'u' : 'U'; } else if (ch.equals("v")) { newArray[i] = isLower ? 'v' : 'V'; } else if (ch.equals("w")) { newArray[i] = isLower ? 'w' : 'W'; } else if (ch.equals("x")) { newArray[i] = isLower ? 'x' : 'X'; } else if (ch.equals("y")) { newArray[i] = isLower ? 'y' : 'Y'; } else if (ch.equals("z")) { newArray[i] = isLower ? 'z' : 'Z'; } else if (ch.equals("0")) { newArray[i] = '0'; } else if (ch.equals("1")) { newArray[i] = '1'; } else if (ch.equals("2")) { newArray[i] = '2'; } else if (ch.equals("3")) { newArray[i] = '3'; } else if (ch.equals("4")) { newArray[i] = '4'; } else if (ch.equals("5")) { newArray[i] = '5'; } else if (ch.equals("6")) { newArray[i] = '6'; } else if (ch.equals("7")) { newArray[i] = '7'; } else if (ch.equals("8")) { newArray[i] = '8'; } else if (ch.equals("9")) { newArray[i] = '9'; } else { newArray[i] = defaultChar; } } StringBuffer newString = new StringBuffer(); StringTokenizer tokens = new StringTokenizer(new String(newArray), new String(new char[] { defaultChar })); if (tokens.hasMoreTokens()) { newString.append(tokens.nextToken()); } while (tokens.hasMoreTokens()) { newString.append(new String(new char[] { defaultChar })).append(tokens.nextToken()); } return newString.toString(); } public static String getHiddenValueFieldName(OperationNode targetNode, ActionNode startNode) { return getHiddenValueAccessorName(targetNode, startNode).toUpperCase(); } public static String getHiddenValueAccessorName(OperationNode targetNode, ActionNode startNode) { return ToolBox.getJavaName(new StringBuffer(targetNode.getName()).append("_FROM_").append(startNode.getName()).append("_") .append(startNode.getFlexoID())); } public static String nameForRepositoryAndIdentifier(GenerationRepository repository, String identifier) { return repository.getName() + "." + identifier; } }