Package er.directtoweb

Source Code of er.directtoweb.ERD2WRule

package er.directtoweb;

import com.webobjects.directtoweb.Assignment;
import com.webobjects.directtoweb.Rule;
import com.webobjects.eocontrol.EOAndQualifier;
import com.webobjects.eocontrol.EOKeyValueArchiver;
import com.webobjects.eocontrol.EOKeyValueUnarchiver;
import com.webobjects.eocontrol.EOQualifier;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSMutableDictionary;

import er.extensions.foundation.ERXProperties;

/**
* Rule class that works around two problems:
* <ul>
* <li>when you have an assignment class that is not present in the classpath
* then the model will not load, making for very strange errors. We replace the
* missing class with the normal assignment class and log the error.
* <li>when evaluating rule priorities, the default is to place rules containing <code>pageConfiguration</code>
* keys so high up that they will get preferred over rules without such a condition, but with a higher author setting.
* This is pretty ridiculous and leads to having to set <code>... AND (pageConfiguration like '*')</code>
* in all the conditions.<br>
* We place rules with a <code>pageConfiguration</code> so high that they will be higher than rules with the same author setting
* but lower than a rule with a higher setting.
* </ul>
* <br>In order to be usable with the D2WClient and Rule editor, we also patch the encoded
* dictionary so these tools find no trace of the patched rules.
* @author ak
*/
public class ERD2WRule extends Rule {
  /**
   * Do I need to update serialVersionUID?
   * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the
   * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a>
   */
  private static final long serialVersionUID = 1L;

    private int _priority = -1;
    private String _assignmentClassName;
    private boolean patchRulePriority = ERXProperties.booleanForKeyWithDefault("er.directtoweb.ERD2WRule.patchRulePriority", true);

    public ERD2WRule() {
        super();
    }

    public ERD2WRule(EOKeyValueUnarchiver eokeyvalueunarchiver) {
        super(eokeyvalueunarchiver.decodeIntForKey("author"),
                ((EOQualifier) eokeyvalueunarchiver.decodeObjectForKey("lhs")),
                ((Assignment) eokeyvalueunarchiver.decodeObjectForKey("rhs")));
        _assignmentClassName = (String)eokeyvalueunarchiver.decodeObjectForKey("assignmentClassName");
    }
   
    public static Object decodeWithKeyValueUnarchiver(EOKeyValueUnarchiver eokeyvalueunarchiver) {
        ERD2WRule rule = null;
        try {
            rule = new ERD2WRule(eokeyvalueunarchiver);
        } catch(Throwable t) {
            // AK: this occurs mostly when we want to load a rule that contains an assigment class which can't be found
            //HACK cheesy way to get at the encoded rule dictionary
            NSMutableDictionary dict = (NSMutableDictionary)NSKeyValueCoding.Utility.valueForKey(eokeyvalueunarchiver,"propertyList");
            String ruleString = dict.toString();
            // now store the old assignment class
            dict.takeValueForKeyPath(dict.valueForKeyPath("rhs.class"), "assignmentClassName");
            // and push in the default class
            dict.takeValueForKeyPath(Assignment.class.getName(), "rhs.class");
            // try again
            try {
                rule = new ERD2WRule(eokeyvalueunarchiver);
                ruleString = rule.toString();
               
            } finally {
                ERD2WModel.log.error("Problems with this rule: \n" +  t + "\n" + ruleString, t);
            }
        }
        return rule;
    }
   
    /**
     * Overridden to patch the normal rule class name into the generated dictionary.
     * @see com.webobjects.eocontrol.EOKeyValueArchiving#encodeWithKeyValueArchiver(com.webobjects.eocontrol.EOKeyValueArchiver)
     */
    @Override
    public void encodeWithKeyValueArchiver (EOKeyValueArchiver eokeyvaluearchiver) {
        super.encodeWithKeyValueArchiver(eokeyvaluearchiver);
        ((NSMutableDictionary)eokeyvaluearchiver.dictionary()).setObjectForKey(Rule.class.getName(), "class");
    }
   
    /**
     * Overridden to work around
     * @see com.webobjects.directtoweb.Rule#priority()
     */
    @Override
    public int priority() {
      if (!patchRulePriority) {
        // TC - Added for MZ because we have thousands of rules and don't want to comb through all of them to change their priorities.
        return super.priority();
      }
        if(_priority == -1) {
           
            EOQualifier lhs = lhs();
            String lhsString = "";
                          
            _priority = 1000 * author();

            if(lhs != null) {
                lhsString = lhs.toString();
                if(lhsString.indexOf("dummyTrue") == -1) {
                    if(lhsString.indexOf("pageConfiguration") != -1) {
                        _priority += 500;
                    }
                    if(lhs() instanceof EOAndQualifier) {
                        _priority += ((EOAndQualifier)lhs()).qualifiers().count();
                    } else {
                        _priority ++;
                    }
                }
            }
        }
        return _priority;
    }

    public String assignmentClassName() {
        if(_assignmentClassName == null) {
            _assignmentClassName = rhs().getClass().getName();
        }
        return _assignmentClassName;
    }
   
    public ERD2WRule cloneRule() {
        EOKeyValueArchiver archiver = new EOKeyValueArchiver();
        encodeWithKeyValueArchiver(archiver);
        EOKeyValueUnarchiver unarchiver = new EOKeyValueUnarchiver(archiver.dictionary());
       
        return new ERD2WRule(unarchiver);
    }
   
    /**
     * Builds a string like:<br>
     * <pre><code>   100: ((entity.name = 'Bug') and (task = 'edit')) => isInspectable = true [com.directtowen.BooleanAssignment]</code></pre>
     * @return a nice description of the rule
     */
    @Override
    public String toString() {
        String prefix = "      ";
        String rhsClass = assignmentClassName();
        return (
                prefix.substring(0, prefix.length() - ("" + author()).length()) + author() + " : " +
                (lhs() == null ? "*true*" : lhs().toString()) +
                " => " +
                (rhs() == null ? "<NULL>" : rhs().keyPath() + " = " + rhs().value() +
                        ( rhsClass.equals(Assignment.class.getName()) ? "" : " [" + rhsClass + "]")
                ) +
                " (" + priority() + ")");
    }
}
TOP

Related Classes of er.directtoweb.ERD2WRule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.