Search in sources :

Example 1 with JaffaRulesFrameworkException

use of org.jaffa.rules.JaffaRulesFrameworkException in project jaffa-framework by jaffa-projects.

the class CandidateKeyValidator method invoke.

/**
 * Apply the candidate-key validation.
 */
private void invoke(String targetClassName, IPersistent targetObject, UOW uow, RuleMetaData rule, AtomicCriteria criteriaToDiscardCurrentObject, Map<String, Object> keyValueMap) throws ApplicationException, ApplicationExceptions, FrameworkException {
    if (log.isDebugEnabled()) {
        log.debug("Applying " + rule + " on " + targetObject);
    }
    Criteria criteria = null;
    String ck = rule.getParameter(RuleMetaData.PARAMETER_VALUE);
    String[] ckFields = ck.split(",");
    Boolean ignoreNull = Parser.parseBoolean(rule.getParameter("ignore-null"));
    // Flex fields having null values are deleted from the database table.
    // The persistence engine does not support queries of the type 'where not exists...'.
    // Hence we'll retrieve all rows and throw an exception only if the fields in the collection are null in any of the rows
    Collection<String> nullFields = null;
    FlexClass flexClass = targetObject instanceof IFlexFields && ((IFlexFields) targetObject).getFlexBean() != null ? (FlexClass) ((IFlexFields) targetObject).getFlexBean().getDynaClass() : null;
    boolean keyModified = false;
    for (String ckField : ckFields) {
        // determine if this is a flex field
        FlexProperty flexProperty = flexClass != null ? flexClass.getDynaProperty(ckField) : null;
        // Obtain the value
        Object ckValue;
        try {
            ckValue = BeanHelper.getField(flexProperty != null ? ((IFlexFields) targetObject).getFlexBean() : targetObject, ckField);
            if (ignoreNull != null && ignoreNull && ckValue == null) {
                if (log.isDebugEnabled())
                    log.debug("Rule will be ignored since " + ckField + " is null");
                return;
            }
        } catch (Exception e) {
            if (log.isDebugEnabled())
                log.debug("Exception thrown while trying to get value for the property " + ckField + ". It may not exist in the targetObject", e);
            return;
        }
        // Perform the check only if the field is modified, or is NULL and Object has not been saved yet
        if (!keyModified)
            keyModified = isModified(flexProperty != null ? ((IFlexFields) targetObject).getFlexBean() : targetObject, ckField) || (ckValue == null && !targetObject.isDatabaseOccurence());
        // and any other rule may cause the actual update to be executed.
        if (flexProperty != null && flexProperty.getFlexInfo() != null && flexProperty.getFlexInfo().getProperty("domain-mapping") != null) {
            ckField = flexProperty.getFlexInfo().getProperty("domain-mapping");
            flexProperty = null;
        }
        // Add to criteria
        if (criteria == null)
            criteria = new Criteria();
        if (ckValue == null) {
            if (flexProperty != null) {
                if (nullFields == null)
                    nullFields = new LinkedList<String>();
                nullFields.add(ckField);
            } else {
                criteria.addCriteria(StringHelper.getUpper1(ckField), Criteria.RELATIONAL_IS_NULL);
            }
        } else {
            if (flexProperty != null) {
                Criteria flexCriteria = new Criteria();
                flexCriteria.setTable(FlexFieldMeta.getName());
                int i = 0;
                for (String key : keyValueMap.keySet()) flexCriteria.addInnerCriteria("Key" + ++i, StringHelper.getUpper1(key));
                flexCriteria.addCriteria(FlexFieldMeta.OBJECT_NAME, flexClass.getLogicalName());
                flexCriteria.addCriteria(FlexFieldMeta.FIELD_NAME, flexProperty.getLogicalName());
                flexCriteria.addCriteria(FlexFieldMeta.VALUE, DataTypeMapper.instance().map(ckValue, String.class, flexProperty.getFlexInfo() != null ? flexProperty.getFlexInfo().getProperty("layout") : null));
                criteria.addAggregate(flexCriteria);
            } else {
                criteria.addCriteria(StringHelper.getUpper1(ckField), ckValue);
            }
        }
    }
    if (keyModified && criteria != null) {
        if (criteriaToDiscardCurrentObject != null)
            criteria.addAtomic(criteriaToDiscardCurrentObject);
        criteria.setTable(targetClassName);
        // try {
        for (Object o : uow.query(criteria)) {
            boolean violation = nullFields == null;
            if (!violation) {
                // Not a violation if any of the fields is not null
                for (String ckField : nullFields) {
                    try {
                        violation = BeanHelper.getField(targetObject, ckField) == null;
                        if (!violation) {
                            break;
                        }
                    } catch (Exception e) {
                        if (log.isDebugEnabled()) {
                            log.debug("Error in invoke method during query execution.", e);
                        }
                        throw new JaffaRulesFrameworkException("Error in invoke method during query execution on object: " + targetClassName, null, e);
                    }
                }
            }
            if (violation) {
                if (log.isDebugEnabled()) {
                    log.debug("Candidate key '" + ck + "' is not unique for the object " + targetObject);
                }
                String objectLabel = getObjectLabel(targetClassName, targetObject);
                StringBuilder ckLabel = new StringBuilder();
                for (int i = 0; i < ckFields.length; i++) {
                    if (i > 0) {
                        ckLabel.append(',');
                    }
                    ckLabel.append(getPropertyLabel(targetObject, ckFields[i]));
                }
                throw wrapException(new DuplicateCandidateKeyException(objectLabel, ckLabel.toString()), (T) targetObject, rule);
            }
        }
    }
}
Also used : FlexProperty(org.jaffa.flexfields.FlexProperty) AtomicCriteria(org.jaffa.persistence.AtomicCriteria) Criteria(org.jaffa.persistence.Criteria) IFlexFields(org.jaffa.flexfields.IFlexFields) FlexClass(org.jaffa.flexfields.FlexClass) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException) FrameworkException(org.jaffa.exceptions.FrameworkException) DuplicateCandidateKeyException(org.jaffa.exceptions.DuplicateCandidateKeyException) ApplicationException(org.jaffa.exceptions.ApplicationException) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException) DuplicateCandidateKeyException(org.jaffa.exceptions.DuplicateCandidateKeyException)

Example 2 with JaffaRulesFrameworkException

use of org.jaffa.rules.JaffaRulesFrameworkException in project jaffa-framework by jaffa-projects.

the class CandidateKeyValidator method validateProperty.

/**
 * {@inheritDoc}
 */
@Override
protected void validateProperty(T targetObject, String targetPropertyName, Object targetPropertyValue, List<RuleMetaData> rules, UOW uow) throws ApplicationException, FrameworkException {
    String targetClassName = getActualClassName(targetObject.getClass());
    IPersistent persistentTargetObject = null;
    try {
        // Use the associated persistentObject for a FlexBean instance
        if (targetObject instanceof FlexBean && ((FlexBean) targetObject).getPersistentObject() != null) {
            persistentTargetObject = ((FlexBean) targetObject).getPersistentObject();
            targetClassName = persistentTargetObject.getClass().getName();
        }
        // This rules makes sense on IPersistent instances only. Bail out on all other instances
        if (!(targetObject instanceof IPersistent)) {
            return;
        } else if (persistentTargetObject == null) {
            persistentTargetObject = (IPersistent) targetObject;
        }
        // Obtain a Map containing key fields and corresponding values
        Map<String, Object> keyValueMap = getKeyValueMap(targetClassName, (IPersistent) targetObject);
        // Create a criteria such that the current object is not included in the search for candidate-key violations
        AtomicCriteria criteriaToDiscardCurrentObject = createCriteriaToDiscardCurrentObject(persistentTargetObject, keyValueMap);
        // Invoke each rule
        for (RuleMetaData rule : rules) {
            invoke(targetClassName, persistentTargetObject, uow, rule, criteriaToDiscardCurrentObject, keyValueMap);
        }
    } catch (ApplicationExceptions e) {
        if (log.isDebugEnabled()) {
            log.debug("Error in validateProperty method for object: " + targetClassName, e);
        }
        throw new JaffaRulesFrameworkException("Error in validateProperty method for object: " + targetClassName, null, e);
    }
}
Also used : ApplicationExceptions(org.jaffa.exceptions.ApplicationExceptions) IPersistent(org.jaffa.persistence.IPersistent) AtomicCriteria(org.jaffa.persistence.AtomicCriteria) RuleMetaData(org.jaffa.rules.meta.RuleMetaData) FlexBean(org.jaffa.flexfields.FlexBean) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException)

Example 3 with JaffaRulesFrameworkException

use of org.jaffa.rules.JaffaRulesFrameworkException in project jaffa-framework by jaffa-projects.

the class MetaDataWriter method write.

/**
 * Writes the supplied meta data into the supplied source file
 */
public static void write(ClassMetaDataDto cmd) throws MetaDataWriterException {
    if (cmd.getSourceFileName() == null) {
        log.error("No source folder was supplied for meta data export.");
        throw new MetaDataWriterException(MetaDataWriterException.SOURCE_NOT_FOUND);
    }
    Document document = null;
    try {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        document = builder.newDocument();
    } catch (javax.xml.parsers.ParserConfigurationException dbe) {
        log.error("No source folder was supplied for meta data export.");
        throw new MetaDataWriterException(MetaDataWriterException.PARSE_ERROR, null, dbe);
    }
    Element aop = document.createElement("aop");
    Element metadata = document.createElement("metadata");
    metadata.setAttribute("tag", "jaffa.rules");
    metadata.setAttribute("class", cmd.getName());
    if (cmd.getExecutionRealm() != null && !cmd.getExecutionRealm().equals(""))
        metadata.setAttribute("execution-realm", cmd.getExecutionRealm());
    if (cmd.getExtendsClass() != null && !cmd.getExtendsClass().equals(""))
        metadata.setAttribute("extends-class", cmd.getExtendsClass());
    if (cmd.getLanguage() != null && !cmd.getLanguage().equals(""))
        metadata.setAttribute("language", cmd.getLanguage());
    if (cmd.getCondition() != null && !cmd.getCondition().equals(""))
        metadata.setAttribute("condition", cmd.getCondition());
    List<RuleMetaDataDto> classRules = cmd.getRules();
    if (classRules != null) {
        for (RuleMetaDataDto classRule : classRules) {
            Rule ruleInfo = RuleRepository.instance().getRuleByName(classRule.getRuleName());
            Element propertyRule = document.createElement(classRule.getRuleName());
            Map<String, String> params = classRule.getParameters();
            Boolean customProcess = false;
            // If label rule contains a token and a tokenValue then update applicationResources with the new token value
            if (classRule.getRuleName().equals("label")) {
                String token = null, value = null;
                if (params != null) {
                    for (Map.Entry<String, String> param : params.entrySet()) {
                        if (param.getKey().equals("token")) {
                            token = param.getValue();
                        }
                        if (param.getKey().equals("tokenValue")) {
                            value = param.getValue();
                        }
                    }
                }
                if (token != null && value != null) {
                    try {
                        LabelHelper.setLabel(token, value);
                    } catch (FrameworkException e) {
                        log.debug(e.getLocalizedMessage());
                    }
                    customProcess = true;
                }
            }
            if (!customProcess) {
                if (params != null) {
                    for (Map.Entry<String, String> param : params.entrySet()) {
                        if (ruleInfo != null && ruleInfo.getTextParameter() != null && ruleInfo.getTextParameter().equals(param.getKey())) {
                            propertyRule.setTextContent(param.getValue());
                        } else {
                            propertyRule.setAttribute(param.getKey(), param.getValue());
                        }
                    }
                }
                metadata.appendChild(propertyRule);
            }
        }
    }
    List<PropertyMetaDataDto> fields = cmd.getProperties();
    List<String> processedProperties = new LinkedList<String>();
    if (fields != null) {
        for (PropertyMetaDataDto field : fields) {
            if (processedProperties.indexOf(field.getPropertyName().toLowerCase()) >= 0) {
                log.error("Property has been defined multiple times: " + field.getPropertyName());
                throw new MetaDataWriterException(MetaDataWriterException.DUPLICATE_PROPERTY);
            }
            processedProperties.add(field.getPropertyName().toLowerCase());
            Element property = document.createElement("property");
            property.setAttribute("name", field.getPropertyName());
            if (field.getExtendsProperty() != null && !field.getExtendsProperty().equals(""))
                metadata.setAttribute("extends-property", field.getExtendsProperty());
            if (field.getExtendsClass() != null && !field.getExtendsClass().equals(""))
                metadata.setAttribute("extends-class", field.getExtendsClass());
            if (field.getLanguage() != null && !field.getLanguage().equals(""))
                metadata.setAttribute("language", field.getLanguage());
            if (field.getCondition() != null && !field.getCondition().equals(""))
                property.setAttribute("condition", field.getCondition());
            List<RuleMetaDataDto> rules = field.getRules();
            if (rules != null) {
                for (RuleMetaDataDto rule : rules) {
                    Rule ruleInfo = RuleRepository.instance().getRuleByName(rule.getRuleName());
                    Element propertyRule = document.createElement(rule.getRuleName());
                    Map<String, String> params = rule.getParameters();
                    if (params != null) {
                        for (Map.Entry<String, String> param : params.entrySet()) {
                            if (ruleInfo != null && ruleInfo.getTextParameter() != null && ruleInfo.getTextParameter().equals(param.getKey())) {
                                propertyRule.setTextContent(param.getValue());
                            } else {
                                propertyRule.setAttribute(param.getKey(), param.getValue());
                            }
                        }
                    }
                    property.appendChild(propertyRule);
                }
            }
            metadata.appendChild(property);
        }
    }
    aop.appendChild(metadata);
    document.appendChild(aop);
    File file = null;
    try {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
        DOMSource source = new DOMSource(document);
        String filteredSourceFileName = FileFilter.filterUserInputFileName(cmd.getSourceFileName());
        if (filteredSourceFileName == null) {
            log.error("Error resolving source file name.");
            throw new IllegalArgumentException();
        }
        file = new File(new URI(filteredSourceFileName));
        log.debug("Writing aop file to: " + file.getAbsolutePath());
        File parentDir = file.getParentFile();
        if (!parentDir.exists())
            parentDir.mkdirs();
        StreamResult result = new StreamResult(file);
        transformer.transform(source, result);
    } catch (javax.xml.transform.TransformerException te) {
        log.error("Error writing xml document into file.");
        throw new MetaDataWriterException(MetaDataWriterException.XML_PARSE_ERROR, null, te);
    } catch (URISyntaxException se) {
        log.error("Source path could not be converted to URI");
        throw new MetaDataWriterException(MetaDataWriterException.SOURCE_NOT_FOUND, null, se);
    }
    try {
        MetaDataRepository.instance().unload(file.toURI().toString());
        AopXmlLoader.getInstance().processAopPaths(Collections.singletonList(file.toString().toString()));
    } catch (JaffaRulesFrameworkException jrfe) {
        log.error("Error loading/unloading class meta data from file.");
        throw new MetaDataWriterException(MetaDataWriterException.FILE_ERROR, null, jrfe);
    }
}
Also used : DOMSource(javax.xml.transform.dom.DOMSource) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) RuleMetaDataDto(org.jaffa.rules.dto.RuleMetaDataDto) Transformer(javax.xml.transform.Transformer) Element(org.w3c.dom.Element) URISyntaxException(java.net.URISyntaxException) Document(org.w3c.dom.Document) URI(java.net.URI) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException) TransformerFactory(javax.xml.transform.TransformerFactory) FrameworkException(org.jaffa.exceptions.FrameworkException) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException) StreamResult(javax.xml.transform.stream.StreamResult) LinkedList(java.util.LinkedList) DocumentBuilder(javax.xml.parsers.DocumentBuilder) PropertyMetaDataDto(org.jaffa.rules.dto.PropertyMetaDataDto) Rule(org.jaffa.rules.rulemeta.Rule) Map(java.util.Map) File(java.io.File)

Example 4 with JaffaRulesFrameworkException

use of org.jaffa.rules.JaffaRulesFrameworkException in project jaffa-framework by jaffa-projects.

the class ForeignKeyValidator method validateKey.

/**
 * Apply the foreign-key validation at the property-level.
 */
private void validateKey(T targetObject, String[] fkFields, Object[] fkValues, RuleMetaData rule) throws ApplicationException, JaffaRulesFrameworkException {
    if (log.isDebugEnabled()) {
        log.debug("Applying the check " + rule + " for the fields " + StringHelper.stringArrayToString(fkFields) + " on " + targetObject);
    }
    // Find the 'public static boolean exists(UOW uow, Object key...)' method
    Method m = findMethod(fkFields, rule);
    // Invoke the 'public static boolean exists(UOW uow, Object key...)' method
    Boolean result;
    try {
        result = (Boolean) m.invoke(null, fkValues);
    } catch (Exception e) {
        throw new JaffaRulesFrameworkException(e.getMessage(), null, e);
    }
    if (result == null || !result) {
        String domainLabel = getObjectLabel(m.getDeclaringClass().getName(), null);
        StringBuilder fkLabel = new StringBuilder();
        for (int i = 0; i < fkFields.length; i++) {
            if (i > 0) {
                fkLabel.append(',');
            }
            fkLabel.append(getPropertyLabel(targetObject, fkFields[i]));
        }
        String fieldKeyLabel = fkLabel.toString();
        String primaryKeyLabel = getPrimaryKeyLabel(m.getDeclaringClass().getName(), null);
        if (primaryKeyLabel == null) {
            primaryKeyLabel = fieldKeyLabel;
        }
        if (log.isDebugEnabled()) {
            log.debug("ForeignKey validation for the value '" + fkValues + "' of '" + fkFields + "' failed against the domainObject '" + m.getDeclaringClass().getName() + '\'');
        }
        Object[] arguments = getErrorArgumentArray(targetObject, rule);
        if (arguments.length == 0) {
            arguments = new Object[] { domainLabel, primaryKeyLabel };
        }
        throw wrapException(new InvalidForeignKeyException(fkLabel.toString(), arguments), targetObject, rule);
    }
}
Also used : InvalidForeignKeyException(org.jaffa.datatypes.exceptions.InvalidForeignKeyException) Method(java.lang.reflect.Method) InvalidForeignKeyException(org.jaffa.datatypes.exceptions.InvalidForeignKeyException) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException) InvalidRuleParameterException(org.jaffa.rules.rulemeta.InvalidRuleParameterException) FrameworkException(org.jaffa.exceptions.FrameworkException) ApplicationException(org.jaffa.exceptions.ApplicationException) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException)

Example 5 with JaffaRulesFrameworkException

use of org.jaffa.rules.JaffaRulesFrameworkException in project jaffa-framework by jaffa-projects.

the class PartialForeignKeyValidator method validateProperty.

/**
 * {@inheritDoc}
 */
@Override
protected void validateProperty(T targetObject, String targetPropertyName, Object targetPropertyValue, List<RuleMetaData> rules, UOW uow) throws ApplicationException, FrameworkException {
    if (targetPropertyValue != null) {
        for (RuleMetaData rule : rules) {
            if (log.isDebugEnabled()) {
                log.debug("Applying " + rule + " on " + targetPropertyValue);
            }
            String domainName = rule.getParameter(PARAMETER_DOMAIN_NAME);
            String propName = rule.getParameter(PARAMETER_PROPERTY_NAME);
            if (propName == null) {
                propName = targetPropertyName;
            }
            propName = StringHelper.getUpper1(propName);
            Criteria c = new Criteria();
            c.setTable(domainName);
            c.addCriteria(propName, targetPropertyValue);
            if (!uow.query(c).iterator().hasNext()) {
                String className;
                try {
                    className = Class.forName(domainName).getName();
                } catch (ClassNotFoundException e) {
                    throw new JaffaRulesFrameworkException(e.getMessage(), null, e);
                }
                // Invalid value. Display the list of valid values in the error message
                // It is valid for multiple row to be returned so we don't check for that here
                String domainLabel = getObjectLabel(className, null);
                String fkLabel = getPropertyLabel(targetObject, targetPropertyName);
                String primaryKeyLabel = getPrimaryKeyLabel(className, null);
                if (primaryKeyLabel == null) {
                    primaryKeyLabel = fkLabel.toString();
                }
                if (log.isDebugEnabled()) {
                    log.debug("PartialForeignKey validation for the value '" + targetPropertyValue + "' of '" + targetPropertyName + "' failed against the domainObject '" + domainName + '\'');
                }
                String errorCode = getErrorCode(primaryKeyLabel, rule);
                Object[] arguments = getErrorArgumentArray(targetObject, rule);
                if (arguments == null) {
                    arguments = new Object[] { domainLabel, primaryKeyLabel };
                }
                throw wrapException(new InvalidForeignKeyException(errorCode, arguments), targetObject, rule);
            }
        }
    }
}
Also used : InvalidForeignKeyException(org.jaffa.datatypes.exceptions.InvalidForeignKeyException) RuleMetaData(org.jaffa.rules.meta.RuleMetaData) Criteria(org.jaffa.persistence.Criteria) JaffaRulesFrameworkException(org.jaffa.rules.JaffaRulesFrameworkException)

Aggregations

JaffaRulesFrameworkException (org.jaffa.rules.JaffaRulesFrameworkException)10 FrameworkException (org.jaffa.exceptions.FrameworkException)6 ApplicationException (org.jaffa.exceptions.ApplicationException)5 DocumentBuilder (javax.xml.parsers.DocumentBuilder)3 RuleMetaData (org.jaffa.rules.meta.RuleMetaData)3 Document (org.w3c.dom.Document)3 Method (java.lang.reflect.Method)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 InvalidForeignKeyException (org.jaffa.datatypes.exceptions.InvalidForeignKeyException)2 DuplicateCandidateKeyException (org.jaffa.exceptions.DuplicateCandidateKeyException)2 FlexBean (org.jaffa.flexfields.FlexBean)2 AtomicCriteria (org.jaffa.persistence.AtomicCriteria)2 Criteria (org.jaffa.persistence.Criteria)2 File (java.io.File)1 Field (java.lang.reflect.Field)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 DocumentBuilderFactory (javax.xml.parsers.DocumentBuilderFactory)1