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 }