Term.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2011,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.kernel.bo.parser;
017 
018 import java.util.ArrayList;
019 import java.util.List;
020 
021 import org.qedeq.base.trace.Trace;
022 import org.qedeq.base.utility.StringUtility;
023 
024 /**
025  * Parsed term.
026  *
027  @version $Revision: 1.1 $
028  @author  Michael Meyling
029  */
030 public class Term {
031 
032     /** This class. */
033     private static final Class CLASS = Term.class;
034 
035     /** Operator, can be <code>null</code>. */
036     private final Operator operator;
037 
038     /** Arguments, can be <code>null</code>. */
039     private final List arguments;
040 
041     /** Atom, can be <code>null</code>. */
042     private final TermAtom atom;
043 
044     /**
045      * Constructor.
046      *
047      @param   atom    Term atom.
048      */
049     public Term(final TermAtom atom) {
050         this.operator = null;
051         this.arguments = null;
052         this.atom = atom;
053     }
054 
055 
056     /**
057      * Constructor.
058      *
059      @param   operator    Construct new term for this operator.
060      */
061     public Term(final Operator operator) {
062         this.operator = operator;
063         this.arguments = new ArrayList();
064         this.atom = null;
065     }
066 
067     /**
068      * Constructor.
069      *
070      @param   operator        Construct new term for this operator.
071      @param   firstArgument   First argument of operator.
072      */
073     public Term(final Operator operator, final Term firstArgument) {
074         this.operator = operator;
075         this.arguments = new ArrayList();
076         this.atom = null;
077         addArgument(firstArgument);
078     }
079 
080     /**
081      * Is this term an atom?
082      *
083      @return  Is this term an atom?
084      */
085     public final boolean isAtom() {
086         return atom != null;
087     }
088 
089     /**
090      * Add next argument term to operator. Overall number of arguments must
091      * not exceed {@link Operator#getMax()} (if <code>>= 0</code>). Addition is only possible if
092      * this is no atom term (see {@link #Term(TermAtom)}).
093      *
094      @param   term    Add this argument at last position.
095      @throws  IllegalArgumentException    This is an atom term or argument
096      *          maximum exceeded.
097      */
098     public final void addArgument(final Term term) {
099         if (isAtom()) {
100             throw new IllegalArgumentException(
101                 "this is an atom, no arguments could be added to " + atom.getValue());
102         }
103         if (operator.getMax() >= && operator.getMax() < arguments.size() 1) {
104             throw new IllegalArgumentException("operator could have maximal "
105                 + operator.getMax() " arguments");
106         }
107         arguments.add(term);
108     }
109 
110     /**
111      * Get operator of term. Can be <code>null</code> if this is an atom term.
112      *
113      @return  Term operator.
114      */
115     public final Operator getOperator() {
116         return operator;
117     }
118 
119     /**
120      * Get number of arguments of this operator.
121      *
122      @return  Argument number.
123      */
124     public final int size() {
125         if (arguments == null) {
126             return 0;
127         }
128         return arguments.size();
129     }
130 
131     /**
132      * Get QEDEQ representation of this term.
133      *
134      @return  QEDEQ representation.
135      */
136     public final String getQedeq() {
137         if (isAtom()) {
138             return atom.getValue();
139         else {
140             final StringBuffer buffer = new StringBuffer();
141             buffer.append(operator.getQedeq()).append('(');
142             if (operator.getQedeqArgument() != null) {
143                 buffer.append(StringUtility.quote(operator.getQedeqArgument()));
144             }
145             for (int i = 0; i < arguments.size(); i++) {
146                 if (i > || operator.getQedeqArgument() != null) {
147                     buffer.append(", ");
148                 }
149                 buffer.append(((Term)
150                     arguments.get(i)).getQedeq());
151             }
152             buffer.append(')');
153             return buffer.toString();
154         }
155     }
156 
157     /**
158      * Get QEDEQ XML representation of this term.
159      *
160      @return  QEDEQ XML representation.
161      */
162     public final String getQedeqXml() {
163         return getQedeqXml(0);
164     }
165 
166     /**
167      * Get QEDEQ XML representation of this term.
168      *
169      @param   level   Tabulation level.
170      @return  QEDEQ XML representation.
171      */
172     private final String getQedeqXml(final int level) {
173         if (isAtom()) {
174             return StringUtility.getSpaces(level * 2+ atom.getValue() "\n";
175         else {
176             final StringBuffer buffer = new StringBuffer();
177             buffer.append(StringUtility.getSpaces(level * 2));
178             buffer.append("<").append(operator.getQedeq());
179             if (operator.getQedeq().endsWith("VAR")) {  // TODO mime 20060612: ok for all QEDEQ?
180                 buffer.append(" id=" + quote(operator.getQedeqArgument()));
181                 if (arguments == null || arguments.size() == 0) {
182                     buffer.append(" />" "\n");
183                     return buffer.toString();
184                 }
185             else if (operator.getQedeq().endsWith("CON")) {
186                 buffer.append(" ref=" + quote(operator.getQedeqArgument()));
187                 if (arguments == null || arguments.size() == 0) {
188                     buffer.append(" />" "\n");
189                     return buffer.toString();
190                 }
191             }
192 
193             buffer.append(">\n");
194             if (operator.getQedeqArgument() != null && !operator.getQedeq().endsWith("VAR")
195                     && !operator.getQedeq().endsWith("CON")) {
196                 // no arguments expected!
197                 Trace.fatal(CLASS, this, "getQedeqXml(int)""operator argument is not null but: "
198                     + operator.getQedeqArgument()new IllegalArgumentException());
199             }
200             for (int i = 0; i < arguments.size(); i++) {
201                 buffer.append(((Term)
202                     arguments.get(i)).getQedeqXml(level + 1));
203             }
204             buffer.append(StringUtility.getSpaces(level * 2));
205             buffer.append("</").append(operator.getQedeq()).append(">\n");
206             return buffer.toString();
207         }
208     }
209 
210     /**
211      * Quote attribute value.
212      *
213      @param   text    Attribute text.
214      @return  Quoted attribute.
215      */
216     private String quote(final String text) {
217         return "\"" + StringUtility.replace(text, "\"""&quot;""\"";
218     }
219 
220 }