View Javadoc

1   package cz.cuni.amis.pogamut.sposh.elements;
2   
3   import cz.cuni.amis.pogamut.sposh.exceptions.DuplicateNameException;
4   import cz.cuni.amis.pogamut.sposh.exceptions.InvalidNameException;
5   import cz.cuni.amis.pogamut.sposh.exceptions.UnexpectedElementException;
6   import java.util.ArrayList;
7   import java.util.List;
8   import java.awt.datatransfer.DataFlavor;
9   
10  /**
11   * CompetenceElement is basically one of choices of the competence. It has a
12   * name(not used elsewhere in the tree, but unique), trigger and defined action
13   * that should be done if the triggers is satisfied.
14   * <p/>
15   * Example in POSH:
16   * <pre>(move (trigger ((see-player))) move-player)</pre>
17   *
18   * @author HonzaH
19   */
20  public final class CompetenceElement extends PoshDummyElement<CompetenceElement, Competence> implements INamedElement {
21  
22      /**
23       * Name of the choice.
24       */
25      private String name;
26      /**
27       * If this element is during one traversal evaluated for elegibility more
28       * times than the this number, it is automatically unelegible for the
29       * remainder of the traversal.
30       *
31       * @deprecated Because nobody is using it. Also not very useful.
32       */
33      @Deprecated
34      private int retries;
35      /**
36       * Comment about this choice.
37       *
38       * @deprecated Because editor doesn't support it
39       */
40      @Deprecated
41      private String comment;
42      /**
43       * Trigger of this choice. If satisfied, the action will be pursued.
44       */
45      private final Trigger<CompetenceElement> trigger = new Trigger<CompetenceElement>(this);
46      /**
47       * Action of this choice.
48       */
49      private final TriggeredAction action;
50      /**
51       * Property name of {@link CompetenceElement#name}.
52       */
53      public static final String ceName = "ceName";
54      /**
55       * Property name of {@link CompetenceElement#retries}.
56       */
57      public static final String ceRetries = "ceRetries";
58      /**
59       * Property name of {@link CompetenceElement#comment}.
60       */
61      public static final String ceComment = "ceComment";
62      /**
63       * Data flavor of competence element, used for drag and drop.
64       */
65      public static final DataFlavor dataFlavor = new DataFlavor(CompetenceElement.class, "competence-element");
66      /**
67       * Special value for infinite number of retries.
68       *
69       * @see CompetenceElement#getRetries()
70       */
71      public static final int INFINITE_RETRIES = -1;
72  
73      /**
74       * Create a choice.
75       *
76       * @param name Name of a choice
77       * @param triggerSenses List of senses that will trigger the action of this
78       * choice
79       * @param actionCall Action call(=action name with arguments), name can be a
80       * normal action, an AP/C name.
81       */
82      public CompetenceElement(String name, List<Sense> triggerSenses, PrimitiveCall actionCall, int retries, String comment) {
83          assert name != null;
84          assert comment != null;
85  
86          this.name = name;
87          this.retries = retries;
88          this.comment = comment;
89          this.action = LapElementsFactory.createAction(actionCall);
90          this.action.setParent(this);
91  
92          for (Sense sense : triggerSenses) {
93              trigger.add(sense);
94          }
95      }
96  
97      /**
98       * Get trigger of this choice. Trigger can contain number of senses that are
99       * evaluated (along with retries) to determine elegibility of the element
100      * for traversal.
101      *
102      */
103     public Trigger<CompetenceElement> getTrigger() {
104         return trigger;
105     }
106 
107     /**
108      * Get action of this choice.
109      *
110      * @return Action of this choice.
111      */
112     public TriggeredAction getAction() {
113         return action;
114     }
115 
116     @Override
117     public String toString() {
118         StringBuilder sb = new StringBuilder();
119         sb.append('(');
120         sb.append(name);
121         if (!trigger.isEmpty()) {
122             sb.append(" (trigger ");
123             sb.append(trigger.toString());
124             sb.append(')');
125         }
126         sb.append(' ');
127         sb.append(action.toString());
128         if (retries != INFINITE_RETRIES) {
129             sb.append(' ');
130             sb.append(retries);
131         }
132         if (!comment.isEmpty()) {
133             sb.append(" \"");
134             sb.append(comment);
135             sb.append('"');
136         }
137         sb.append(')');
138 
139         return sb.toString();
140     }
141 
142     @Override
143     public List<PoshElement> getChildDataNodes() {
144         List<PoshElement> children = new ArrayList<PoshElement>(trigger);
145         children.add(action);
146         return children;
147     }
148 
149     @Override
150     public String getName() {
151         return name;
152     }
153 
154     /**
155      * Set name of this choice.
156      *
157      * @param name new name of this choice.
158      */
159     public void setName(String name) throws InvalidNameException, DuplicateNameException {
160         name = name.trim();
161         if (!name.matches(IDENT_PATTERN)) {
162             throw InvalidNameException.create(name);
163         }
164         boolean isSameName = this.name.equals(name);
165         if (getParent() != null && isUsedName(name, getParent().getChildDataNodes()) && !isSameName) {
166             throw new DuplicateNameException("Choice with " + name + " already exists in competence " + getParent().getName());
167         }
168         
169         String oldName = this.name;
170         this.name = name;
171         firePropertyChange(ceName, oldName, name);
172 
173     }
174 
175     @Override
176     public boolean moveChild(int newIndex, PoshElement child) {
177         assert child instanceof Sense;
178         trigger.moveSense(newIndex, (Sense)child);
179         return true;
180     }
181 
182     @Override
183     public DataFlavor getDataFlavor() {
184         return dataFlavor;
185     }
186 
187     @Override
188     public LapType getType() {
189         return LapType.COMPETENCE_ELEMENT;
190     }
191 
192     /**
193      * When engine is evaluating drive and it encounteres a node How many
194      * retries can this element experience before it is removed from list of
195      * elegible elements for current traverasal.
196      *
197      * @return
198      * @deprecated Remnants of original posh,
199      */
200     @Deprecated
201     public int getRetries() {
202         return retries;
203     }
204 
205     /**
206      * Change number of allowed retries of this node and fire the change.
207      *
208      * @param newRetries new number of retries. Must be &ge;0 or {@link CompetenceElement#INFINITE_RETRIES}.
209      * @deprecated Not used in the editor
210      */
211     @Deprecated
212     public void setRetries(int newRetries) {
213         assert newRetries >= 0 || newRetries == INFINITE_RETRIES;
214 
215         int oldValue = retries;
216         retries = newRetries;
217         firePropertyChange(ceRetries, oldValue, newRetries);
218     }
219 
220     /**
221      * Get comment for this element.
222      *
223      * @return Comment, not null(maybe blank)
224      * @deprecated Not supported in the editor.
225      */
226     @Deprecated
227     public String getComment() {
228         return comment;
229     }
230 
231     /**
232      * Change the comment of this element and fire the change.
233      *
234      * @param newComment New comment of this element
235      * @deprecated Not used in the editor
236      */
237     @Deprecated
238     public void setComment(String newComment) {
239         assert newComment != null;
240         String oldComment = comment;
241         comment = newComment;
242         firePropertyChange(ceComment, oldComment, newComment);
243     }
244 }