XNSIO
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Brett’s Refactoring Exercise Solution Take 1

Saturday, June 13th, 2009

Recently Brett Schuchert from Object Mentor has started posting code snippets on his blog and inviting people to refactor it. Similar to the Daily Refactoring Teaser that I’m conducting at Directi. (I’m planning to make it public soon).

Following is my refactored solution (take 1) to the poorly written code.

Wrote some Acceptance Test to understand how the RpnCalculator works:

Then I updated the perform method to

@Deprecated
public void perform(final String operatorName) {
  perform(operators.get(operatorName));
}
 
public void perform(final Operator operator) {
  operator.eval(stack);
  currentMode = Mode.inserting;
}

Notice I’ve deprecated the old method which takes String. I want to kill primitive obsession at its root.

Had to temporarily add the following map (this should go away once our deprecated method is knocked off).

private static Map operators = new HashMap() {
  {
    put("+", Operator.ADD);
    put("-", Operator.SUBTRACT);
    put("!", Operator.FACTORIAL);
  }
 
  @Override
  public Operator get(final Object key) {
    if (!super.containsKey(key)) {
      throw new MathOperatorNotFoundException();
    }
    return super.get(key);
  }
};

Defined various Operators

private static abstract class Operator {
  private static final Operator ADD = new BinaryOperator() {
    @Override
    protected int eval(final int op1, final int op2) {
      return op1 + op2;
    }
  };
 
  private static final Operator SUBTRACT = new BinaryOperator() {
    @Override
    protected int eval(final int op1, final int op2) {
      return op2 - op1;
    }
  };
 
  private static final Operator FACTORIAL = new UnaryOperator() {
    @Override
    protected int eval(final int op1) {
      int result = 1;
      int currentOperandValue = op1;
      while (currentOperandValue > 1) {
        result *= currentOperandValue;
        --currentOperandValue;
      }
      return result;
    }
  };
 
  public abstract void eval(final OperandStack stack);
}

Declared two types of Operators (BinaryOperator and UnaryOperator) to avoid duplication and to make it easy for adding new operators.

public static abstract class BinaryOperator extends Operator {
  @Override
  public void eval(final OperandStack s) {
    s.push(eval(s.pop(), s.pop()));
  }
 
  protected abstract int eval(int op1, int op2);
}

and

public static abstract class UnaryOperator extends Operator {
  @Override
  public void eval(final OperandStack s) {
    s.push(eval(s.pop()));
  }
 
  protected abstract int eval(int op1);
}

svn: Unable to open an ra_local session to URL

Monday, August 4th, 2008

Currently I’m working on adding Revision Control support to FitNesse. In the process, I’m creating a SVN adapter using svnkit library.

Once I’ve added a file, if I try to commit the file using

1
2
3
4
5
6
protected void commit(File file) throws SVNException {
final SVNClientManager manager = SVNClientManager.newInstance();
final SVNCommitClient commitClient = manager.getCommitClient();
final File[] filesToCommit = new File[] { file };
commitClient.doCommit(filesToCommit, false, "Auto Commit", false, false);
}

I get the following exception:

1
2
3
4
5
svn: Unable to open an ra_local session to URL
at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.error(SVNErrorManager.java:55)
at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.error(SVNErrorManager.java:40)
at org.tmatesoft.svn.core.wc.SVNCommitClient.doCommit(SVNCommitClient.java:582)
at org.tmatesoft.svn.core.wc.SVNCommitClient.doCommit(SVNCommitClient.java:549)

Trying to Google for this, did not take me anywhere. Finally after debugging thru svnkit’s code, I stumbled upon the following line which throws the exception:

1
SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIDecoded(url));

Basically, they have SVNRepositoryFactory class which expects the client to register an appropriate driver to handle the given protocol. Their javadocs says:

Depending on what protocol a user exactly would like to use to access the repository he should first of all set up an appropriate extension of this factory. So, if the user is going to work with the repository via the custom svn-protocol (or svn+xxx) he initially calls

1
SVNRepositoryFactoryImpl.setup();

More details: http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/io/SVNRepositoryFactory.html

Solution: Since I’m using File System (file://) protocol, I had to add the following line in a static block of my adapter class:

1
FSRepositoryFactory.setup();
    Licensed under
Creative Commons License