KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > transformers > RomanTransformer


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util.transformers;
11
12 import java.util.regex.*;
13
14 /**
15  * Static utilities to deal with roman numbers, and non static functions to transform strings
16  * representing decimal numbers to roman numbers and back.
17  *
18  * @author Michiel Meeuwissen
19  * @since MMBase-1.8
20  * @version $Id: RomanTransformer.java,v 1.4 2005/11/01 23:36:02 michiel Exp $
21  */

22
23 public class RomanTransformer extends StringTransformer {
24
25     public static final Pattern NUMERIC = Pattern.compile("\\d+");
26     public static final Pattern ROMAN = Pattern.compile("(?i)[ivxlcdm]+");
27
28
29     /**
30      * Constants for roman numbers
31      */

32     public static final int I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000;
33
34     /**
35      * Converts one of the letters from the roman number system to an int.
36      * @return <code>0</code> if could not be converted
37      */

38     public static int romanToDecimal(char r) {
39         if (r == 'i') return I;
40         if (r == 'v') return V;
41         if (r == 'x') return X;
42         if (r == 'l') return L;
43         if (r == 'c') return C;
44         if (r == 'd') return D;
45         if (r == 'm') return M;
46         return 0;
47     }
48     /**
49      * Converts an integer to one the letters of the roman number system, or ' ' if no such number.
50      * @see #decimalToRoman(int)
51      */

52     
53     public static char decimalToRomanDigit(int i) {
54         switch(i) {
55         case M: return 'm';
56         case D: return 'd';
57         case C: return 'c';
58         case L: return 'l';
59         case X: return 'x';
60         case V: return 'v';
61         case I: return 'i';
62         default: return ' ';
63         }
64     }
65     
66     /**
67      * Converts roman number to int.
68      */

69      public static int romanToDecimal(String JavaDoc roman) {
70         roman = roman.toLowerCase();
71         int tot = 0;
72         int mode = I;
73         for (int i = roman.length() - 1; i >= 0 ; i--) {
74             int value = romanToDecimal(roman.charAt(i));
75
76             if (value > mode) mode = value;
77             if (value < mode) {
78                 tot -= value;
79             } else {
80                 tot += value;
81             }
82         }
83             
84         return tot;
85     }
86     /**
87      * Converts int to roman number (if bigger than 0, smaller then 4000), other wise return the
88      * integer as a string.
89     */

90     public static String JavaDoc decimalToRoman(int value) {
91         if (value < 1 || value > 3999) {
92             // throw new IllegalArgumentException("Only natural numbers smaller than 4000 can be
93
// presented as a roman number");
94
return "" + value;
95         }
96         final StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
97         int mode = M;
98         while (value > 0) {
99             while (value < mode) mode /= 10;
100             if (value >= 9 * mode && mode < M) {
101                 buf.append(decimalToRomanDigit(mode));
102                 buf.append(decimalToRomanDigit(mode * 10));
103                 value -= 9 * mode;
104                 continue;
105             }
106             if (value >= 4 * mode && mode < M) {
107                 if (value < 5 * mode) {
108                     buf.append(decimalToRomanDigit(mode));
109                     value += mode;
110                 }
111                 buf.append(decimalToRomanDigit(5 * mode));
112                 value -= 5 * mode;
113             }
114             while (value >= mode) {
115                 buf.append(decimalToRomanDigit(mode));
116                 value -= mode;
117             }
118         }
119         return buf.toString();
120     }
121
122
123     // javadoc inherited
124
public String JavaDoc transform(String JavaDoc r) {
125         try {
126             int i = Integer.parseInt(r);
127             return decimalToRoman(i);
128         } catch (Exception JavaDoc e) {
129             return r;
130         }
131     }
132
133     // javadoc inherited
134
public String JavaDoc transformBack(String JavaDoc r) {
135         return "" + romanToDecimal(r);
136     }
137
138     public String JavaDoc toString() {
139         return "ROMAN";
140     }
141
142
143     /**
144      * Just to test
145      */

146     public static void main(String JavaDoc argv[]) {
147         if (argv.length == 0) {
148             System.out.println("Use roman or decimal argument");
149             return;
150         }
151         if (argv.length == 1) {
152             if (NUMERIC.matcher(argv[0]).matches()) {
153                 System.out.println(decimalToRoman(Integer.parseInt(argv[0])));
154             } else {
155                 System.out.println(romanToDecimal(argv[0]));
156             }
157         }
158     }
159
160 }
161
Popular Tags