Java tutorial
/** * This file is part of SIMPL4(http://simpl4.org). * * Copyright [2014] [Manfred Sattler] <manfred@ms123.org> * * SIMPL4 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. * * SIMPL4 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 SIMPL4. If not, see <http://www.gnu.org/licenses/>. */ package org.ms123.common.data; import flexjson.JSONDeserializer; import flexjson.JSONSerializer; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.PrintStream; import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.jdo.PersistenceManager; import javax.jdo.annotations.PersistenceCapable; import org.apache.commons.beanutils.BeanMap; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.fileupload.FileItem; import org.apache.tika.detect.DefaultDetector; import org.apache.tika.detect.Detector; import org.apache.tika.io.TikaInputStream; import org.apache.tika.metadata.Metadata; import org.apache.tika.mime.MediaType; import org.apache.tika.Tika; import org.joda.time.DateTime; import org.ms123.common.data.api.SessionContext; import org.ms123.common.data.scripting.MVELEvaluator; import org.ms123.common.libhelper.Inflector; import org.ms123.common.permission.api.PermissionService; import org.ms123.common.team.api.TeamService; import org.ms123.common.utils.IOUtils; import org.ms123.common.utils.TypeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.ms123.common.entity.api.Constants.STATE_FIELD; import org.ms123.common.libhelper.Base64; import groovy.lang.*; import org.codehaus.groovy.control.*; import javax.transaction.UserTransaction; import javax.jdo.Extent; import javax.jdo.JDOObjectNotFoundException; import javax.jdo.PersistenceManager; import javax.jdo.Query; import java.lang.reflect.Field; @SuppressWarnings("unchecked") public class MultiOperations { protected static Inflector m_inflector = Inflector.getInstance(); protected static JSONSerializer m_js = new JSONSerializer(); private static String FIELDNAME_REGEX = "[a-zA-Z0-9_.]{2,64}"; public static List<Object> persistObjects(SessionContext sc, Object obj, Map<String, Object> persistenceSpecification, int max) { m_js.prettyPrint(true); List<Object> retList = new ArrayList(); UserTransaction ut = sc.getUserTransaction(); String mainEntity = null; Collection<Object> resultList = null; if (obj instanceof Collection) { resultList = (Collection) obj; } else { resultList = new ArrayList(); resultList.add(obj); } debug("persistObjects:" + resultList + ",persistenceSpecification:" + persistenceSpecification); String parentFieldName = null; Class parentClazz = null; String parentQuery = null; String updateQuery = null; Boolean noUpdate = false; PersistenceManager pm = sc.getPM(); Context context = new Context(); context.shell = new GroovyShell(MultiOperations.class.getClassLoader(), new Binding(), new CompilerConfiguration()); if (persistenceSpecification != null) { String parentLookup = (String) persistenceSpecification.get("lookupRelationObjectExpr"); String relation = (String) persistenceSpecification.get("relation"); if (!Utils.isEmpty(parentLookup) && !Utils.isEmpty(relation)) { String s[] = relation.split(","); parentClazz = sc.getClass(Utils.getBaseName(s[0])); parentFieldName = s[1]; if (parentLookup.matches(FIELDNAME_REGEX)) { String q = isString(parentClazz, parentLookup) ? "'" : ""; parentQuery = parentLookup + " == " + q + "${" + parentLookup + "}" + q; } else if (parentLookup.matches(FIELDNAME_REGEX + "," + FIELDNAME_REGEX)) { s = parentLookup.split(","); String q = isString(parentClazz, s[1]) ? "'" : ""; parentQuery = s[0] + " == " + q + "${" + s[1] + "}" + q; } else { parentQuery = parentLookup; } } String updateLookup = (String) persistenceSpecification.get("lookupUpdateObjectExpr"); Class mainClass = null; if (resultList.size() > 0) { mainClass = resultList.iterator().next().getClass(); } if (!Utils.isEmpty(updateLookup) && mainClass != null) { if (updateLookup.matches(FIELDNAME_REGEX)) { String q = isString(mainClass, updateLookup) ? "'" : ""; updateQuery = updateLookup + " == " + q + "${" + updateLookup + "}" + q; } else { updateQuery = updateLookup; } noUpdate = (Boolean) persistenceSpecification.get("noUpdate"); if (noUpdate == null) noUpdate = false; } } debug("noUpdate:" + noUpdate); Map hintsMap = new HashMap(); hintsMap.put("noUpdate", noUpdate); try { int num = 0; if (resultList.size() > 0) { Class clazz = resultList.iterator().next().getClass(); mainEntity = m_inflector.getEntityName(clazz.getSimpleName()); String pk = TypeUtils.getPrimaryKey(clazz); sc.setPrimaryKey(pk); } for (Object object : resultList) { if (max != -1 && num >= max) { break; } Map m = SojoObjectFilter.getObjectGraph(object, sc, true, 2); //retList.add(m); Object origObject = null; boolean isNew = true; if (updateQuery != null) { origObject = getObjectByFilter(context, pm, object.getClass(), object, updateQuery); debug("origObject:" + origObject); if (origObject != null) { populate(sc, m, origObject, hintsMap); object = origObject; isNew = false; } } if (origObject == null && parentClazz != null) { Object parentObject = getObjectByFilter(context, pm, parentClazz, object, parentQuery); origObject = getOrigObjectFromParent(mainEntity, parentObject, parentFieldName); if (origObject == null || !origObject.getClass().equals(object.getClass())) { sc.getDataLayer().insertIntoMaster(sc, object, mainEntity, parentObject, parentFieldName); } else { populate(sc, m, origObject, hintsMap); object = origObject; isNew = false; } } if ((num % 500) == 0) { System.out.println("num:" + num); } //Muss eigentlich ber alle Object gehen evaluteFormulas(sc, mainEntity, object, "in", isNew); setStateToNew(object); sc.getDataLayer().makePersistent(sc, object); retList.add(object); num++; } } catch (Throwable e) { e.printStackTrace(); sc.handleException(ut, e); } finally { sc.handleFinally(ut); } return retList; } private static void setStateToNew(Object object) { try { boolean hasState = PropertyUtils.isWriteable(object, STATE_FIELD); if (hasState) { PropertyUtils.setProperty(object, STATE_FIELD, null); } } catch (Exception e) { } } private static Object getObjectByFilter(Context context, PersistenceManager pm, Class clazz, Object child, String queryString) throws Exception { String filter = expandString(context, queryString, new BeanMap(child)); debug("getObjectByFilter:" + filter + "/clazz:" + clazz); Extent e = pm.getExtent(clazz, true); Query q = pm.newQuery(e, filter); try { Collection coll = (Collection) q.execute(); Iterator iter = coll.iterator(); if (iter.hasNext()) { Object obj = iter.next(); debug("getObjectByFilter:found"); return obj; } } finally { q.closeAll(); } debug("getObjectByFilter:not found"); return null; } public static Object getOrigObjectFromParent(String entityName, Object objectMaster, String fieldName) throws Exception { debug("getOrigObjectFromParent:" + objectMaster + "/" + entityName + "/" + fieldName); if (objectMaster == null) return null; String propertyName = fieldName; if (fieldName.equals(entityName)) { propertyName = m_inflector.pluralize(entityName).toLowerCase(); } Class clazz = PropertyUtils.getPropertyType(objectMaster, propertyName); if (clazz == null) { clazz = PropertyUtils.getPropertyType(objectMaster, fieldName); } if (clazz != null) { if (clazz.equals(java.util.List.class) || clazz.equals(java.util.Set.class)) { return null; } else { if (fieldName.equals(entityName)) { propertyName = m_inflector.singularize(entityName).toLowerCase(); } return PropertyUtils.getProperty(objectMaster, propertyName); } } return null; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //populate //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static void populate(SessionContext sessionContext, Map sourceMap, Object destinationObj, Map hintsMap) { PersistenceManager pm = sessionContext.getPM(); if (hintsMap == null) { hintsMap = new HashMap(); } boolean noUpdate = Utils.getBoolean(hintsMap, "noUpdate", false); BeanMap destinationMap = new BeanMap(destinationObj); String entityName = m_inflector.getEntityName(destinationObj.getClass().getSimpleName()); debug("populate.sourceMap:" + sourceMap + ",destinationObj:" + destinationObj + ",destinationMap:" + destinationMap + "/hintsMap:" + hintsMap + "/entityName:" + entityName); if (sourceMap == null) { return; } debug("populate(" + entityName + ") is a persistObject:" + javax.jdo.JDOHelper.isPersistent(destinationObj) + "/" + javax.jdo.JDOHelper.isNew(destinationObj)); if (sourceMap.get("id") != null) { debug("populate(" + entityName + ") has id:" + sourceMap.get("id")); return; } Map permittedFields = sessionContext.getPermittedFields(entityName, "write"); Iterator<String> it = sourceMap.keySet().iterator(); while (it.hasNext()) { String propertyName = it.next(); boolean permitted = sessionContext.getPermissionService().hasAdminRole() || "team".equals(entityName) || sessionContext.isFieldPermitted(propertyName, entityName, "write"); if (!propertyName.startsWith("_") && !permitted) { debug("---->populate:field(" + propertyName + ") no write permission"); continue; } else { debug("++++>populate:field(" + propertyName + ") write permitted"); } String datatype = null; String edittype = null; if (!propertyName.startsWith("_")) { Map config = (Map) permittedFields.get(propertyName); if (config != null) { datatype = (String) config.get("datatype"); edittype = (String) config.get("edittype"); } } if (propertyName.equals(STATE_FIELD) && !sessionContext.getPermissionService().hasAdminRole()) { continue; } if ("auto".equals(edittype)) continue; String mode = null; Map hm = (Map) hintsMap.get(propertyName); if (hm != null) { Object m = hm.get("mode"); if (m != null && m instanceof String) { mode = (String) m; } if (mode == null) { m = hm.get("useit"); if (m != null && m instanceof String) { mode = (String) m; } } } if (mode == null) { mode = "replace"; } Class propertyClass = destinationMap.getType(propertyName); debug("\ttype:" + propertyClass + "(" + propertyName + "=" + sourceMap.get(propertyName) + ")"); if ("_ignore_".equals(sourceMap.get(propertyName))) { continue; } if (propertyClass == null) { debug("\t--- Warning property not found:" + propertyName); } else if (propertyClass.equals(java.util.Date.class)) { String value = Utils.getString(sourceMap.get(propertyName), destinationMap.get(propertyName), mode); debug("\tDate found:" + propertyName + "=>" + value); Date date = null; if (value != null) { try { Long val = Long.valueOf(value); date = (Date) ConvertUtils.convert(val, Date.class); debug("\tdate1:" + date); } catch (Exception e) { try { DateTime dt = new DateTime(value); date = new Date(dt.getMillis()); debug("\tdate2:" + date); } catch (Exception e1) { try { int space = value.indexOf(" "); if (space != -1) { value = value.substring(0, space) + "T" + value.substring(space + 1); DateTime dt = new DateTime(value); date = new Date(dt.getMillis()); } debug("\tdate3:" + date); } catch (Exception e2) { debug("\terror setting date:" + e); } } } } debug("\tsetting date:" + date); destinationMap.put(propertyName, date); } else if (propertyClass.equals(java.util.Map.class)) { info("!!!!!!!!!!!!!!!!!!!Map not implemented"); } else if (propertyClass.equals(java.util.List.class) || propertyClass.equals(java.util.Set.class)) { boolean isList = propertyClass.equals(java.util.List.class); boolean isSimple = false; if (datatype != null && datatype.startsWith("list_")) { isSimple = true; } try { Class propertyType = TypeUtils.getTypeForField(destinationObj, propertyName); debug("propertyType:" + propertyType + " fill with: " + sourceMap.get(propertyName) + ",list:" + destinationMap.get(propertyName) + "/mode:" + mode); Collection sourceList = isList ? new ArrayList() : new HashSet(); Object fromVal = sourceMap.get(propertyName); if (fromVal instanceof String && ((String) fromVal).length() > 0) { info("FromVal is StringSchrott, ignore"); continue; } if (sourceMap.get(propertyName) instanceof Collection) { sourceList = (Collection) sourceMap.get(propertyName); } if (sourceList == null) { sourceList = isList ? new ArrayList() : new HashSet(); } Collection destinationList = (Collection) PropertyUtils.getProperty(destinationObj, propertyName); debug("destinationList:" + destinationList); debug("sourceList:" + sourceList); if (destinationList == null) { destinationList = isList ? new ArrayList() : new HashSet(); PropertyUtils.setProperty(destinationObj, propertyName, destinationList); } if ("replace".equals(mode)) { boolean isEqual = false; if (isSimple) { isEqual = Utils.isCollectionEqual(destinationList, sourceList); if (!isEqual) { destinationList.clear(); } debug("\tisEqual:" + isEqual); } else { List deleteList = new ArrayList(); String namespace = sessionContext.getStoreDesc().getNamespace(); for (Object o : destinationList) { if (propertyType.getName().endsWith(".Team")) { int status = sessionContext.getTeamService().getTeamStatus(namespace, new BeanMap(o), null, sessionContext.getUserName()); debug("populate.replace.teamStatus:" + status + "/" + new HashMap(new BeanMap(o))); if (status != -1) { pm.deletePersistent(o); deleteList.add(o); } } else { pm.deletePersistent(o); deleteList.add(o); } } for (Object o : deleteList) { destinationList.remove(o); } } debug("populate.replace.destinationList:" + destinationList + "/" + propertyType.getName()); if (isSimple) { if (!isEqual) { for (Object o : sourceList) { destinationList.add(o); } } } else { for (Object o : sourceList) { Map childSourceMap = (Map) o; Object childDestinationObj = propertyType.newInstance(); if (propertyType.getName().endsWith(".Team")) { childSourceMap.remove("id"); Object desc = childSourceMap.get("description"); Object name = childSourceMap.get("name"); Object dis = childSourceMap.get("disabled"); String teamid = (String) childSourceMap.get("teamid"); Object ti = Utils.getTeamintern(sessionContext, teamid); if (desc == null) { childSourceMap.put("description", PropertyUtils.getProperty(ti, "description")); } if (name == null) { childSourceMap.put("name", PropertyUtils.getProperty(ti, "name")); } if (dis == null) { childSourceMap.put("disabled", false); } pm.makePersistent(childDestinationObj); populate(sessionContext, childSourceMap, childDestinationObj, hintsMap); PropertyUtils.setProperty(childDestinationObj, "teamintern", ti); } else { pm.makePersistent(childDestinationObj); populate(sessionContext, childSourceMap, childDestinationObj, hintsMap); } debug("populated.add:" + new HashMap(new BeanMap(childDestinationObj))); destinationList.add(childDestinationObj); } } } else if ("remove".equals(mode)) { if (isSimple) { for (Object o : sourceList) { if (destinationList.contains(o)) { destinationList.remove(o); } } } else { for (Object ol : sourceList) { Map childSourceMap = (Map) ol; Object o = Utils.listContainsId(destinationList, childSourceMap, "teamid"); if (o != null) { destinationList.remove(o); pm.deletePersistent(o); } } } } else if ("add".equals(mode)) { if (isSimple) { for (Object o : sourceList) { destinationList.add(o); } } else { for (Object ol : sourceList) { Map childSourceMap = (Map) ol; Object childDestinationObj = Utils.listContainsId(destinationList, childSourceMap, "teamid"); if (childDestinationObj != null) { populate(sessionContext, childSourceMap, childDestinationObj, hintsMap); } else { childDestinationObj = propertyType.newInstance(); if (propertyType.getName().endsWith(".Team")) { Object desc = childSourceMap.get("description"); Object name = childSourceMap.get("name"); Object dis = childSourceMap.get("disabled"); String teamid = (String) childSourceMap.get("teamid"); Object ti = Utils.getTeamintern(sessionContext, teamid); if (desc == null) { childSourceMap.put("description", PropertyUtils.getProperty(ti, "description")); } if (name == null) { childSourceMap.put("name", PropertyUtils.getProperty(ti, "name")); } if (dis == null) { childSourceMap.put("disabled", false); } pm.makePersistent(childDestinationObj); populate(sessionContext, childSourceMap, childDestinationObj, hintsMap); PropertyUtils.setProperty(childDestinationObj, "teamintern", ti); } else { pm.makePersistent(childDestinationObj); populate(sessionContext, childSourceMap, childDestinationObj, hintsMap); } destinationList.add(childDestinationObj); } } } } else if ("assign".equals(mode)) { if (!isSimple) { for (Object ol : sourceList) { Map childSourceMap = (Map) ol; Object childDestinationObj = Utils.listContainsId(destinationList, childSourceMap); if (childDestinationObj != null) { debug("id:" + childSourceMap + " already assigned"); } else { Object id = childSourceMap.get("id"); Boolean assign = Utils.getBoolean(childSourceMap.get("assign")); Object obj = pm.getObjectById(propertyType, id); if (assign) { destinationList.add(obj); } else { destinationList.remove(obj); } } } } } } catch (Exception e) { e.printStackTrace(); debug("populate.list.failed:" + propertyName + "=>" + sourceMap.get(propertyName) + ";" + e); } } else if (propertyClass.equals(java.lang.Boolean.class)) { try { destinationMap.put(propertyName, ConvertUtils.convert(sourceMap.get(propertyName), Boolean.class)); } catch (Exception e) { debug("populate.boolean.failed:" + propertyName + "=>" + sourceMap.get(propertyName) + ";" + e); } } else if (propertyClass.equals(java.lang.Double.class)) { String value = Utils.getString(sourceMap.get(propertyName), destinationMap.get(propertyName), mode); try { destinationMap.put(propertyName, Double.valueOf(value)); } catch (Exception e) { debug("populate.double.failed:" + propertyName + "=>" + value + ";" + e); } } else if (propertyClass.equals(java.lang.Long.class)) { try { destinationMap.put(propertyName, ConvertUtils.convert(sourceMap.get(propertyName), Long.class)); } catch (Exception e) { debug("populate.long.failed:" + propertyName + "=>" + sourceMap.get(propertyName) + ";" + e); } } else if (propertyClass.equals(java.lang.Integer.class)) { debug("Integer:" + ConvertUtils.convert(sourceMap.get(propertyName), Integer.class)); try { destinationMap.put(propertyName, ConvertUtils.convert(sourceMap.get(propertyName), Integer.class)); } catch (Exception e) { debug("populate.integer.failed:" + propertyName + "=>" + sourceMap.get(propertyName) + ";" + e); } } else if ("binary".equals(datatype) || propertyClass.equals(byte[].class)) { InputStream is = null; InputStream is2 = null; try { if (sourceMap.get(propertyName) instanceof FileItem) { FileItem fi = (FileItem) sourceMap.get(propertyName); String name = fi.getName(); byte[] bytes = IOUtils.toByteArray(fi.getInputStream()); if (bytes != null) { debug("bytes:" + bytes.length); } destinationMap.put(propertyName, bytes); is = fi.getInputStream(); is2 = fi.getInputStream(); } else if (sourceMap.get(propertyName) instanceof Map) { Map map = (Map) sourceMap.get(propertyName); String storeLocation = (String) map.get("storeLocation"); is = new FileInputStream(new File(storeLocation)); is2 = new FileInputStream(new File(storeLocation)); byte[] bytes = IOUtils.toByteArray(is); if (bytes != null) { debug("bytes2:" + bytes.length); } is.close(); destinationMap.put(propertyName, bytes); is = new FileInputStream(new File(storeLocation)); } else if (sourceMap.get(propertyName) instanceof String) { String value = (String) sourceMap.get(propertyName); if (value.startsWith("data:")) { int ind = value.indexOf(";base64,"); byte b[] = Base64.decode(value.substring(ind + 8)); destinationMap.put(propertyName, b); is = new ByteArrayInputStream(b); is2 = new ByteArrayInputStream(b); } else { } } else { debug("populate.byte[].no a FileItem:" + propertyName + "=>" + sourceMap.get(propertyName)); continue; } Tika tika = new Tika(); TikaInputStream stream = TikaInputStream.get(is); TikaInputStream stream2 = TikaInputStream.get(is2); String text = tika.parseToString(is); debug("Text:" + text); try { destinationMap.put("text", text); } catch (Exception e) { destinationMap.put("text", text.getBytes()); } //@@@MS Hardcoded try { Detector detector = new DefaultDetector(); MediaType mime = detector.detect(stream2, new Metadata()); debug("Mime:" + mime.getType() + "|" + mime.getSubtype() + "|" + mime.toString()); destinationMap.put("type", mime.toString()); sourceMap.put("type", mime.toString()); } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); debug("populate.byte[].failed:" + propertyName + "=>" + sourceMap.get(propertyName) + ";" + e); } finally { try { is.close(); is2.close(); } catch (Exception e) { } } } else { boolean ok = false; try { Class propertyType = TypeUtils.getTypeForField(destinationObj, propertyName); debug("propertyType:" + propertyType + "/" + propertyName); if (propertyType != null) { boolean hasAnn = propertyType.isAnnotationPresent(PersistenceCapable.class); debug("hasAnnotation:" + hasAnn); if (propertyType.newInstance() instanceof javax.jdo.spi.PersistenceCapable || hasAnn) { handleRelatedTo(sessionContext, sourceMap, propertyName, destinationMap, destinationObj, propertyType); Object obj = sourceMap.get(propertyName); if (obj != null && obj instanceof Map) { Map childSourceMap = (Map) obj; Object childDestinationObj = destinationMap.get(propertyName); if (childDestinationObj == null) { childDestinationObj = propertyType.newInstance(); destinationMap.put(propertyName, childDestinationObj); } populate(sessionContext, childSourceMap, childDestinationObj, hintsMap); } else { if (obj == null) { destinationMap.put(propertyName, null); } } ok = true; } } } catch (Exception e) { e.printStackTrace(); } if (!ok) { String value = Utils.getString(sourceMap.get(propertyName), destinationMap.get(propertyName), mode); try { if (noUpdate) { if (Utils.isEmptyObj(destinationMap.get(propertyName))) { destinationMap.put(propertyName, value); } } else { destinationMap.put(propertyName, value); } } catch (Exception e) { debug("populate.failed:" + propertyName + "=>" + value + ";" + e); } } } } } private static void handleRelatedTo(SessionContext sc, Map sourceMap, String propertyName, BeanMap destinationMap, Object destinationObj, Class propertyType) { Object id = null; try { Object _id = sourceMap.get(propertyName); if (_id != null) { if (_id instanceof Map) { id = ((Map) _id).get("id"); } else { String s = String.valueOf(_id); if (s.indexOf("/") >= 0) { _id = Utils.extractId(s); } Class idClass = PropertyUtils.getPropertyType(propertyType.newInstance(), "id"); id = (idClass.equals(Long.class)) ? Long.valueOf(_id + "") : _id; } } } catch (Exception e) { } if (id != null && !"".equals(id) && !"null".equals(id)) { Object relatedObject = sc.getPM().getObjectById(propertyType, id); /*List<Collection> candidates = TypeUtils.getCandidateLists(relatedObject, destinationObj, null); if (candidates.size() == 1) { Collection l = candidates.get(0); debug("list.contains:" + l.contains(destinationObj)); if (!l.contains(destinationObj)) { l.add(destinationObj); } }*/ destinationMap.put(propertyName, relatedObject); } /*else { Object relatedObject = destinationMap.get(propertyName); debug("\trelatedObject:" + relatedObject); if (relatedObject != null) { List<Collection> candidates = TypeUtils.getCandidateLists(relatedObject, destinationObj, null); if (candidates.size() == 1) { Collection l = candidates.get(0); debug("list.contains:" + l.contains(destinationObj)); if (l.contains(destinationObj)) { l.remove(destinationObj); } } } destinationMap.put(propertyName, null); }*/ } private static synchronized String expandString(Context context, String str, Map<String, String> vars) { String newString = ""; int openBrackets = 0; int first = 0; for (int i = 0; i < str.length(); i++) { if (i < str.length() - 2 && str.substring(i, i + 2).compareTo("${") == 0) { if (openBrackets == 0) { first = i + 2; } openBrackets++; } else if (str.charAt(i) == '}' && openBrackets > 0) { openBrackets -= 1; if (openBrackets == 0) { newString += eval(context, str.substring(first, i), vars); } } else if (openBrackets == 0) { newString += str.charAt(i); } } return newString; } private static void evaluteFormulas(SessionContext sessionContext, String entityName, Object obj, String direction, boolean isNew) { evaluteFormulas(sessionContext, entityName, obj, direction, isNew, null, null); } private static void evaluteFormulas(SessionContext sessionContext, String entityName, Object obj, String direction, boolean isNew, Map<String, Class> involvedClasses, PersistenceManager pm) { Map<String, Object> map = new BeanMap(obj); Map permittedFields = sessionContext.getPermittedFields(entityName); Map<String, Object> result = new HashMap(); Iterator kit = permittedFields.keySet().iterator(); while (kit.hasNext()) { String field = (String) kit.next(); if (permittedFields.get(field) instanceof Map) { Map cm = (Map) permittedFields.get(field); if (cm != null && cm.get("formula_" + direction) != null && !"".equals(cm.get("formula_" + direction))) { if (!"out".equals(direction)) { if (map.get(field) == null) { result.put(field, ""); } } } } } MVELEvaluator evalator = null; if (pm != null) { evalator = new MVELEvaluator((Map) permittedFields.get("_selListMap"), involvedClasses, pm); } else { evalator = new MVELEvaluator((Map) permittedFields.get("_selListMap")); } evalator.setLocalVars(result); evalator.setLocalVars(map); evalator.setLocalVar("se", evalator); evalator.setLocalVar("inflector", m_inflector); evalator.setLocalVar("_isnew", isNew); evalator.setLocalVar("_user", "admin"); Set<String> keyset = new HashSet(map.keySet()); for (String field : keyset) { int dot = field.lastIndexOf("."); String f = field; if (dot != -1) { f = field.substring(dot + 1); } Map cm = (Map) permittedFields.get(f); if (cm != null && cm.get("formula_" + direction) != null && !"".equals(cm.get("formula_" + direction))) { String formula = (String) cm.get("formula_" + direction); Object r = ""; try { r = evalator.eval(formula); debug("evalOk:" + formula + "/" + r); } catch (Exception e) { debug("evalError:" + formula + "/" + e); } result.put(field, r); } } populate(sessionContext, result, obj, null); } private static Object eval(Context context, String expr, Map<String, String> vars) { try { Script script = context.scripCache.get(expr); if (script == null) { script = context.shell.parse(expr); context.scripCache.put(expr, script); } Binding binding = new Binding(vars); script.setBinding(binding); return script.run(); } catch (Throwable e) { e.printStackTrace(); String msg = org.ms123.common.libhelper.Utils.formatGroovyException(e, expr); throw new RuntimeException(msg); } } public static boolean isString(Class clazz, String fieldName) { Field field = null; try { String[] parts = fieldName.split("\\."); for (int i = 0; i < (parts.length - 1); i++) { String part = parts[i]; Field f = clazz.getDeclaredField(part); clazz = f.getType(); fieldName = parts[i + 1]; } field = clazz.getDeclaredField(fieldName); return field.getType().isAssignableFrom(String.class); } catch (Throwable e) { return true; } } private static class Context { public GroovyShell shell; public Map<String, Script> scripCache = new HashMap(); } public static boolean _isString(Class c, String fieldName) { try { Field f = c.getDeclaredField(fieldName); return f.getType().isAssignableFrom(String.class); } catch (Exception e) { return false; } } protected static void debug(String message) { m_logger.debug(message); } protected static void info(String message) { m_logger.info(message); System.out.println(message); } private static final Logger m_logger = LoggerFactory.getLogger(MultiOperations.class); }