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);
}
}
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
}
}
Aggregations