View Javadoc

1   /*
2    * Zemucan: A Syntax Assistant for DB2
3    * Copyright (C) 2009, 2010 Andres Gomez Casanova
4    *
5    * This file is part of Zemucan.
6    *
7    * Zemucan is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as published by
9    * the Free Software Foundation; either version 3 of the License, or
10   * (at your option) any later version.
11   *
12   * Zemucan is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public License
18   * along with this library; if not, see <http://www.gnu.org/licenses/>.
19   *
20   * Contact:
21   * a n g o c a  at  y a h o o  dot  c o m
22   * Cra. 45 No 61 - 31, Bogota, Colombia.
23   *
24   * Author:   $LastChangedBy: angoca $:
25   * Date:     $LastChangedDate: 2011-03-06 09:19:05 -0500 (dom, 06 mar 2011) $:
26   * Revision: $LastChangedRevision: 1910 $:
27   * URL:      $HeadURL: https://zemucan.svn.sourceforge.net/svnroot/zemucan/branches/zemucan_v1/source-code/analyzers/src/main/java/name/angoca/zemucan/core/syntactic/model/GraphAnswer.java $:
28   */
29  package name.angoca.zemucan.core.syntactic.model;
30  
31  import java.util.ArrayList;
32  import java.util.List;
33  
34  import name.angoca.zemucan.GeneralException;
35  import name.angoca.zemucan.core.lexical.model.Token;
36  
37  /**
38   * Represents the answer of a given command. An answer is the phrase completed
39   * or the possible options of the current phrase.
40   * <p>
41   * This object is immutable, once it is created, their properties cannot be
42   * changed. This is the reason because there are not setter methods. The getters
43   * return a copy of the objects in order to prevent an internal modification
44   * from an external context.
45   * <p>
46   * This object returns always a copy of its members.
47   * <p>
48   * <b>Control Version</b>
49   * <p>
50   * <ul>
51   * <li>0.0.1 Class creation.</li>
52   * <li>0.1.0</li>
53   * <li>0.2.0</li>
54   * <li>0.3.0 Recommendations from PMD.</li>
55   * <li>0.3.1 Organized.</li>
56   * <li>0.3.2 not null check.</li>
57   * <li>1.0.0 Moved to version 1.</li>
58   * <li>1.1.0 asserts.</li>
59   * <li>1.1.1 equals fix it.</li>
60   * <li>1.2.0 Clonable.</li>
61   * </ul>
62   *
63   * @author Andres Gomez Casanova <a
64   *         href="mailto:a n g o c a at y a h o o dot c o m" >(AngocA)</a>
65   * @version 1.2.0 2010-05-04
66   */
67  public final class GraphAnswer {
68      /**
69       * Status that indicates if asserts are enabled.
70       */
71      private boolean assertsEnabled;
72  
73      /**
74       * Set of possible options.
75       */
76      private final transient List<Token> options;
77  
78      /**
79       * Phrases that represents the command completed.
80       */
81      private final transient List<Token> phrases;
82  
83      /**
84       * Constructor that associates the phrase and the possible options.
85       *
86       * @param graphPhrases
87       *            phrase completed (could be the same that the user wrote.)
88       * @param graphOptions
89       *            Possible options (0..n)
90       */
91      public GraphAnswer(final List<Token>/* <!>! */graphPhrases,
92              final List<Token>/* <!>! */graphOptions) {
93          assert graphPhrases != null;
94          assert graphOptions != null;
95          this.assertsEnabled = false;
96          // Intentional side-effect!
97          assert this.assertsEnabled = true;
98          if (this.assertsEnabled) {
99              for (final Token token : graphPhrases) {
100                 assert token != null;
101             }
102             for (final Token token : graphOptions) {
103                 assert token != null;
104             }
105         }
106 
107         this.phrases = graphPhrases;
108         this.options = graphOptions;
109     }
110 
111     /*
112      * (non-Javadoc)
113      * @see java.lang.Object#equals(java.lang.Object)
114      */
115     @Override
116     public boolean equals(final Object/* ? */object) {
117         boolean equals = false;
118         if (object instanceof GraphAnswer) {
119             final GraphAnswer graph = (GraphAnswer) object;
120             int size = graph.options.size();
121             if (size == this.options.size()) {
122                 equals = true;
123                 for (int i = 0; (i < size) && equals; i += 1) {
124                     equals &= this.options.contains(graph.options.get(i));
125                 }
126                 size = graph.phrases.size();
127                 if (equals && (size == this.phrases.size())) {
128                     for (int i = 0; (i < size) && equals; i += 1) {
129                         equals &= this.phrases.contains(graph.phrases.get(i));
130                     }
131                 } else {
132                     equals = false;
133                 }
134             }
135         }
136         return equals;
137     }
138 
139     /**
140      * Returns the set of options of the current position.
141      *
142      * @return set of options.
143      * @throws GeneralException
144      *             Problem when cloning.
145      */
146     public List<Token>/* <!>! */getOptions() throws GeneralException {
147         assert this.options != null;
148         if (this.assertsEnabled) {
149             for (final Token token : this.options) {
150                 assert token != null;
151             }
152         }
153 
154         final List<Token> copy = new ArrayList<Token>();
155         for (final Token node : this.options) {
156             try {
157                 copy.add(node.clone());
158             } catch (final CloneNotSupportedException e) {
159                 throw new GeneralException(e);
160             }
161         }
162 
163         return copy;
164     }
165 
166     /**
167      * Returns the set of phrases of the command.
168      *
169      * @return set of tokens that represents the command.
170      * @throws GeneralException
171      *             Problem when cloning.
172      */
173     public List<Token>/* <!>! */getPhrases() throws GeneralException {
174         assert this.phrases != null;
175         if (this.assertsEnabled) {
176             for (final Token token : this.phrases) {
177                 assert token != null;
178             }
179         }
180 
181         final List<Token> copy = new ArrayList<Token>();
182         for (final Token node : this.phrases) {
183             try {
184                 copy.add(node.clone());
185             } catch (final CloneNotSupportedException e) {
186                 throw new GeneralException(e);
187             }
188         }
189 
190         return copy;
191     }
192 
193     /*
194      * (non-Javadoc)
195      * @see java.lang.Object#hashCode()
196      */
197     @Override
198     public int hashCode() {
199         int ret = this.phrases.size() * this.options.size();
200         for (final Token token : this.phrases) {
201             ret -= token.getToken().hashCode();
202         }
203         for (final Token token : this.options) {
204             ret += token.getToken().hashCode();
205         }
206         return ret;
207     }
208 
209     /**
210      * Returns a string representation of a graph answer. The representation is:
211      * [phrases],{options}
212      *
213      * @see java.lang.Object#toString()
214      * @return String representation of a graph answer.
215      */
216     @Override
217     public String/* ! */toString() {
218         final StringBuffer ret = new StringBuffer();
219         ret.append('[');
220         // Phrases
221         for (final Token token : this.phrases) {
222             ret.append(token.toString());
223         }
224         ret.append("],{"); //$NON-NLS-1$
225         // Options
226         for (final Token token : this.options) {
227             ret.append(token.toString());
228         }
229         ret.append('}');
230         return ret.toString();
231     }
232 }