001/*******************************************************************************
002 * Crown Copyright (c) 2006 - 2014, Copyright (c) 2006 - 2014 Kestral Computing P/L.
003 * All rights reserved. This program and the accompanying materials
004 * are made available under the terms of the Eclipse Public License v1.0
005 * which accompanies this distribution, and is available at
006 * http://www.eclipse.org/legal/epl-v10.html
007 * 
008 * Contributors:
009 *    Kestral Computing P/L - initial implementation
010 *******************************************************************************/
011
012package org.fhir.ucum;
013
014import org.fhir.ucum.Canonical.CanonicalUnit;
015
016public class ExpressionComposer {
017
018
019        public String compose(Term term) {
020                if (term == null)
021                        return "1";
022                StringBuilder bldr = new StringBuilder();
023                composeTerm(bldr, term);
024                return bldr.toString();
025        }
026
027        private void composeTerm(StringBuilder bldr, Term term) {
028                if (term.getComp() != null)
029                        composeComp(bldr, term.getComp());
030                if (term.getOp() != null)
031                        composeOp(bldr, term.getOp());
032                if (term.getTerm() != null) { 
033                        composeTerm(bldr, term.getTerm());              
034                }
035        }
036
037        private void composeComp(StringBuilder bldr, Component comp) {
038                if (comp instanceof Factor)
039                        composeFactor(bldr, (Factor)comp);
040                else if (comp instanceof Symbol)
041                        composeSymbol(bldr, (Symbol)comp);
042                else if (comp instanceof Term) {
043                        bldr.append('(');
044                        composeTerm(bldr, (Term)comp);
045                        bldr.append(')');
046                } else
047                        bldr.append('?');
048        }
049
050        private void composeSymbol(StringBuilder bldr, Symbol symbol) {
051                if (symbol.getPrefix() != null) { 
052                        bldr.append(symbol.getPrefix().getCode());
053                }
054                bldr.append(symbol.getUnit().getCode());
055                if (symbol.getExponent() != 1) { 
056                        bldr.append(symbol.getExponent());
057                }
058        }
059
060        private void composeFactor(StringBuilder bldr, Factor comp) {
061           bldr.append(comp.getValue());                
062        }
063
064        private void composeOp(StringBuilder bldr, Operator op) {
065                if (op == Operator.DIVISION)
066                        bldr.append("/");
067                else
068                        bldr.append(".");
069        }
070
071        public String compose(Canonical can) {
072                return compose(can, true);
073        }
074        
075        public String compose(Canonical can, boolean value) {
076          StringBuilder b = new StringBuilder();
077          if (value)
078                b.append(can.getValue().asDecimal());
079          boolean first = true;
080          for (CanonicalUnit c : can.getUnits()) {
081                if (first) first = false; else b.append(".");
082                b.append(c.getBase().getCode());
083                if (c.getExponent() != 1)
084                        b.append(c.getExponent());
085          }
086          return b.toString();
087  }
088
089}