1 /*********************************************************************
2 Copyright 2012, Ralph Ronnquist.
4 This file is part of GORITE.
6 GORITE is free software: you can redistribute it and/or modify it
7 under the terms of the Lesser GNU General Public License as published
8 by the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GORITE is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the Lesser GNU General Public
17 License along with GORITE. If not, see <http://www.gnu.org/licenses/>.
18 **********************************************************************/
20 package com.intendico.data.addon;
22 import com.intendico.data.*;
23 import com.intendico.gorite.addon.Reflector;
24 import com.intendico.gorite.*;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.Observer;
28 import java.util.Vector;
31 * This is a Capability extension that offers the use of predicates in
32 * text form using the language defined by the {@link Language}
35 * <p> The method {@link #textQuery(Data,String)} is used for
36 * immediate {@link com.intendico.data.Query Query} construction,
37 * which is suitable for the {@link Plan#context(Data)}
38 * implementations. The following is an illustration of its use:
41 * addGoal( new Plan( ... ) {
42 * public Query context(Data d) {
43 * return <b>textQuery</b>( d, "And( foo( 45, $x ), bar( $x ) )" );
48 * <p> The method {@link #addRule(String)} provides a deferred {@link
49 * Rule} installation from a text form rule. The following is an
50 * illustration of its use:
53 * addRule( "Lost primary($a,$b,$c) => secondary($a,$c)" );
56 * <p> The method {@link #addReflector(String,String,String)} provides
57 * a deferred {@link Reflector} installation with a text form
58 * query. The following is an illustration of its use:
61 * addReflector( "secondary lost", "percept","Lost secondary($a,$c)" );
64 * The deferred declarations are processed and installed by the first
65 * invokation of the {@link Capability#shareInquirables(Collection)}
66 * method, when all the inquirables have been shared. In that way the
67 * text form references get resolved to actual relations when
68 * translated into the actual {@link Query} or {@link Rule} structure.
70 * <p> Note that more arbitrary conditions in text form predicates
71 * need to be supported by appropriate {@link Inquirable}
72 * implementations. For example, the following could be a way to
73 * define a computed "greater" relation between Integer values:
76 * putInquirable( new Inquirable() {
77 * public String getName() { return "greater"; }
78 * public Query get(final Object [] args) {
79 * return new Condition() {
80 * public boolean condition() {
81 * int a = ((Integer) Ref.deref( args[0] )).intValue();
82 * int b = ((Integer) Ref.deref( args[1] )).intValue();
92 public class TextQueryCapability extends Capability {
95 * Adds a textual rule definition. {@link Rule} creation is set up
96 * to be deferred until after the first {@link
97 * Capability#shareInquirables} invocation.
99 public void addRule(final String rule) {
100 add( new Deferred() {
102 * Installs this as a proper {@link Reflector}.
104 public void install() {
105 Vector/*<Query>*/ q =
106 Language.textToRule( rule, getInquirables().values() );
107 addRule( (Query) q.get( 0 ), (Query) q.get( 1 ) );
113 * Utility method to declare a {@link Reflector} for the owner
114 * {@link Performer} using a text form query. This is deferred to
115 * after the first {@link Capability#shareInquirables(Collection)}
118 public void addReflector(
119 final String goal,final String todo,final String query) {
120 add( new Deferred() {
122 * Installs this as a proper {@link Reflector}.
124 public void install() {
125 Reflector r = new Reflector( getPerformer(), goal, todo );
126 r.addQuery( Language.textToQuery(
128 getInquirables().values(), null, null ),
135 * Utility method that creates a {@link Query} by resolving to the
136 * {@link Capability#inquirables} and the given {@link Data} context.
137 * Note that using this method before inquirables are shared, or more
138 * specifically if relation names are undefined, may result in an
139 * {@link Error}. Further, if the method returns null if the
140 * predicate is not parsable.
142 public Query textQuery(Data data,String predicate) {
143 return Language.textToQuery(
144 predicate, getInquirables().values(), null, data );