Author: ssmiweve
Date: 2008-11-18 12:30:50 +0100 (Tue, 18 Nov 2008)
New Revision: 6947

Added:
   
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/BaseSearchCommandParameter.java
   
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/NavigationSearchCommandParameter.java
   
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/SearchCommandParameter.java
Modified:
   
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/AbstractSearchCommand.java
   
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/Restful.java
   
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/XmlRestful.java
Log:
Issue SKER2149: (Divide & Conquer AbstractSearchCommand to delegates) 
 new Search Command Parameters model/support


Modified: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/AbstractSearchCommand.java
===================================================================
--- 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/AbstractSearchCommand.java
      2008-11-18 08:54:23 UTC (rev 6946)
+++ 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/AbstractSearchCommand.java
      2008-11-18 11:30:50 UTC (rev 6947)
@@ -81,21 +81,19 @@
  * While the SearchCommand interface defines basic execution behavour this 
abstraction defines:<ul>
  * <li>delegation of the call method to the execute method so to provide a 
default implementation for handling
  *      cancellations, thread renaming during execution, and avoidance of 
execution on blank queries,
- * <li>internal visitor pattern to express the query string in the index's 
required manner,</li>
- * <li>helper methods for the internal visitor pattern,</li>
+ * <li>assigned queryBuilder and filterBuilder to express the query and filter 
as the index's requires,</li>
  * <li>delegation to the appropriate query to use (sometimes not the user's 
query),</li>
  * <li>handling and control of the query transformations as defined in the 
commands config,</li>
  * <li>handling and control of the result handlers as defined in the commands 
config,</li>
  * <li>helper methods, beyond the query transformers, for filter (and 
advanced-filter) construction,</li>
- * <li>basic implementation (visitor pattern) for constructing a user 
presentable version of the transformed query.</li>
+ * <li>assigned displayableQueryBuilder for constructing a user presentable 
version of the transformed query,
+ *       that in turn can be parsed again by sesat's query parser to return 
the same query.</li>
  * </ul>
- *                                                                             
                             <br/><br/>
+ *                                        <br/><br/>
  *
- * <b>TODO</b> There is work planned to separate and encapsulate alot of this 
functionality into individual classes.
- *                   http://sesat.no/scarab/issues/id/SKER2149                 
                           <br/><br/>
+ * This command undertook a large refactoring in 2.18 to clean up internal 
concerns.
+ * See the specification [EMAIL PROTECTED] 
http://sesat.no/new-design-proposal-for-searchcommand-and-abstractsearchcommand.html}
  *
- *
- *
  * @version <tt>$Id$</tt>
  */
 public abstract class AbstractSearchCommand extends AbstractReflectionVisitor 
implements SearchCommand, Serializable {
@@ -127,7 +125,7 @@
     private transient final QueryBuilder.Context queryBuilderContext;
     private transient final QueryTransformer initialQueryTransformer;
     private transient final QueryBuilder queryBuilder;
-    private transient final SesamSyntaxQueryBuilder sesamSyntxQueryBuilder;
+    private transient final SesamSyntaxQueryBuilder displayableQueryBuilder;
     private transient final FilterBuilder filterBuilder;
 
     protected final String untransformedQuery;
@@ -135,6 +133,9 @@
     private String transformedQuery;
     private String transformedQuerySesamSyntax;
 
+    private final SearchCommandParameter offsetParameter;
+    private final SearchCommandParameter userSortByParameter;
+
     protected transient final DataModel datamodel;
 
     protected volatile boolean completed = false;
@@ -239,7 +240,7 @@
         queryBuilder = constructQueryBuilder(cxt, queryBuilderContext);
 
         // construct the sesamSyntaxQueryBuilder
-        sesamSyntxQueryBuilder = new 
SesamSyntaxQueryBuilder(queryBuilderContext);
+        displayableQueryBuilder = new 
SesamSyntaxQueryBuilder(queryBuilderContext);
 
         // FIXME implement configuration lookup
         filterBuilder = new BaseFilterBuilder(queryBuilderContext, null);
@@ -247,6 +248,20 @@
         // run an initial queryBuilder run and store the untransformed 
resulting queryString.
         untransformedQuery = getQueryRepresentation();
 
+        // parameters
+
+        offsetParameter = new NavigationSearchCommandParameter(
+                context,
+                getSearchConfiguration().getPagingParameter(),
+                getSearchConfiguration().getPagingParameter(),
+                BaseSearchCommandParameter.Origin.REQUEST);
+
+        userSortByParameter = new NavigationSearchCommandParameter(
+                context,
+                USER_SORT_KEY,
+                USER_SORT_KEY,
+                BaseSearchCommandParameter.Origin.REQUEST);
+
     }
 
     /** Set (or reset) the transformed terms back to the state before any 
queryTransformers were run.
@@ -571,30 +586,14 @@
      */
     protected int getOffset(){
 
-        int offset = 0;
-
-        if(isPaginated()){
-            final String offsetKey = 
getSearchConfiguration().getPagingParameter();
-            final StringDataObject offsetString = 
context.getDataModel().getParameters().getValue(offsetKey);
-            if( null != offsetString ){
-                offset = Integer.parseInt(offsetString.getUtf8UrlEncoded());
-            }
-        }
-        return offset;
+        return null != offsetParameter.getValue()
+                ? Integer.parseInt(offsetParameter.getValue())
+                : 0;
     }
 
     public boolean isPaginated(){
 
-        final boolean navMapExists = null != 
context.getDataModel().getNavigation()
-                && null != 
context.getDataModel().getNavigation().getConfiguration();
-
-        final String offsetKey = getSearchConfiguration().getPagingParameter();
-
-        final Nav offsetNav = navMapExists
-                ? 
context.getDataModel().getNavigation().getConfiguration().getNavMap().get(offsetKey)
-                : null;
-
-        return null != offsetNav && 
getSearchConfiguration().getId().equals(offsetNav.getCommandName());
+        return offsetParameter.isActive();
     }
 
    /**
@@ -608,30 +607,12 @@
     */
     protected String getUserSortBy(){
 
-        String result = null;
-
-        if(isUserSortable()){
-
-            final StringDataObject userSortByString = 
context.getDataModel().getParameters().getValue(USER_SORT_KEY);
-
-            if(null != userSortByString){
-                result = userSortByString.getString();
-            }
-        }
-
-        return result;
+        return userSortByParameter.getValue();
     }
 
     public boolean isUserSortable(){
 
-        final boolean navMapExists = null != 
context.getDataModel().getNavigation()
-                && null != 
context.getDataModel().getNavigation().getConfiguration();
-
-        final Nav sortingNav = navMapExists
-                ? 
context.getDataModel().getNavigation().getConfiguration().getNavMap().get(USER_SORT_KEY)
-                : null;
-
-        return null != sortingNav && 
getSearchConfiguration().getName().equals(sortingNav.getCommandName());
+        return userSortByParameter.isActive();
     }
 
     /**
@@ -834,7 +815,7 @@
 
     protected void updateTransformedQuerySesamSyntax(){
 
-        
setTransformedQuerySesamSyntax(sesamSyntxQueryBuilder.getQueryString());
+        
setTransformedQuerySesamSyntax(displayableQueryBuilder.getQueryString());
     }
 
     protected void setTransformedQuerySesamSyntax(final String sesamSyntax){

Added: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/BaseSearchCommandParameter.java
===================================================================
--- 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/BaseSearchCommandParameter.java
                         (rev 0)
+++ 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/BaseSearchCommandParameter.java
 2008-11-18 11:30:50 UTC (rev 6947)
@@ -0,0 +1,178 @@
+/*
+ * Copyright (2008) Schibsted Søk AS
+ * This file is part of SESAT.
+ *
+ *   SESAT is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Affero General Public License as published 
by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SESAT is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public License
+ *   along with SESAT.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package no.sesat.search.mode.command;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import no.sesat.search.datamodel.generic.StringDataObject;
+import org.apache.log4j.Logger;
+
+/** A base implementation that provides looking up the value in order from a 
number of sources.
+ * Current sources implemented are REQUEST, USER, and CONFIGURATION. <br/><br/>
+ *
+ * isActive() always returns true. subclass to implement dynamic usecases. 
<br/><br/>
+ *
+ * [EMAIL PROTECTED] 
http://sesat.no/new-design-proposal-for-searchcommand-and-abstractsearchcommand.html}
+ * <br/>
+ * @see Origin
+ *
+ * @version $Id$
+ */
+class BaseSearchCommandParameter implements SearchCommandParameter {
+
+    private static final Logger LOG = 
Logger.getLogger(BaseSearchCommandParameter.class);
+
+    protected enum Origin {
+        /**
+         * Obtain the value from the datamodel's parameters.
+         * The plain string representation is returned.
+         * The user must encode or escape if necessary.
+         */
+        REQUEST,
+        /**
+         * Obtain the value from the datamodel's user.
+         */
+        USER,
+        /**
+         * Obtain the value from the SearchConfiguration through introspection.
+         */
+        CONFIGURATION,
+        /**
+         * Obtain the value in a custom manner. getValue() must be overridden 
to provide this 'custom manner'.
+         */
+        CUSTOM
+    };
+
+    private final String name;
+
+    private final Origin[] lookupOrder;
+
+    private transient Origin origin = null;
+
+    private final SearchCommand.Context context;
+
+    BaseSearchCommandParameter(
+            final SearchCommand.Context context,
+            final String name,
+            final Origin... lookupOrder) {
+
+        this.context = context;
+        this.name = name;
+        this.lookupOrder = Arrays.copyOf(lookupOrder, lookupOrder.length);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean isActive() {
+        return true;
+    }
+
+    public String getValue() {
+
+        String result = null;
+        if (isActive()) {
+
+            for (Origin origin : lookupOrder) {
+
+                if (null != this.origin) {
+                    // shortcut to the origin found last time.
+                    origin = this.origin;
+                }
+                switch (origin) {
+
+                    case REQUEST:
+                        final StringDataObject sdo = 
context.getDataModel().getParameters().getValue(name);
+
+                        if (null != sdo) {
+                            result = sdo.getString();
+                        }
+                        break;
+
+                    case USER:
+                        result = 
context.getDataModel().getUser().getUser().getUserPropertiesMap().get(name);
+                        break;
+
+                    case CONFIGURATION:
+
+                        try{
+                            final PropertyDescriptor[] properties = 
Introspector.getBeanInfo(
+                                    
context.getSearchConfiguration().getClass())
+                                    .getPropertyDescriptors();
+
+                            for (PropertyDescriptor property : properties) {
+                                if (name.equals(property.getName())) {
+
+                                    if (null != property.getReadMethod()) {
+
+                                        result = (String) 
property.getReadMethod().invoke(
+                                                
context.getSearchConfiguration(),
+                                                new Object[0]);
+
+                                        break;
+                                    }
+                                }
+                            }
+                        }catch(IntrospectionException ie){
+                            LOG.error("Failed to find parameter", ie);
+                        }catch(IllegalAccessException ie){
+                            LOG.error("Failed to find parameter", ie);
+                        }catch(InvocationTargetException ie){
+                            LOG.error("Failed to find parameter", ie);
+                        }
+                        break;
+
+                    case CUSTOM:
+                        throw new UnsupportedOperationException(
+                                "SearchParameter's with Origin.CUSTOM must 
override getValue");
+                }
+                if (null != result) {
+                    this.origin = origin;
+                    break;
+                }
+            }
+        }
+        return result;
+
+    }
+
+    /** The origin the current value was found from.
+     *
+     * @return the origin the current value was found from.
+     */
+    protected Origin getOrigin() {
+
+        if (null == origin) {
+            getValue();
+        }
+        return origin;
+    }
+
+    /** The context the command is running within.
+     *
+     * @return the context the command is running within.
+     */
+    protected SearchCommand.Context getContext(){
+        return context;
+    }
+
+}


Property changes on: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/BaseSearchCommandParameter.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/NavigationSearchCommandParameter.java
===================================================================
--- 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/NavigationSearchCommandParameter.java
                           (rev 0)
+++ 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/NavigationSearchCommandParameter.java
   2008-11-18 11:30:50 UTC (rev 6947)
@@ -0,0 +1,65 @@
+/*
+* Copyright (2008) Schibsted Søk AS
+ * This file is part of SESAT.
+ *
+ *   SESAT is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Affero General Public License as published 
by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SESAT is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public License
+ *   along with SESAT.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package no.sesat.search.mode.command;
+
+import no.sesat.search.view.navigation.NavigationConfig.Nav;
+
+/** Implementation that handles parameters that are related to the navigation 
configuration.
+ *
+ * @see #isActive()
+ *
+ * @version $Id$
+ */
+class NavigationSearchCommandParameter extends BaseSearchCommandParameter {
+
+    private final String navigationMapKey;
+
+    public NavigationSearchCommandParameter(
+            final SearchCommand.Context context,
+            final String name,
+            final String navigationMapKey,
+            final Origin... lookupOrder) {
+
+        super(context, name, lookupOrder);
+        this.navigationMapKey = navigationMapKey;
+    }
+
+    /** [EMAIL PROTECTED]
+     *
+     * Returns true if there exists from the navigation configuration
+     * a Nav in the NavMap with the key "navigationMapKey"
+     * whos commandName is equal to the current command's name.
+     *
+     * @return [EMAIL PROTECTED]
+     */
+    @Override
+    public boolean isActive() {
+
+        final boolean navMapExists =
+                null != getContext().getDataModel().getNavigation()
+                && null != 
getContext().getDataModel().getNavigation().getConfiguration();
+
+        final Nav nav = navMapExists
+                ? 
getContext().getDataModel().getNavigation().getConfiguration().getNavMap().get(navigationMapKey)
+                : null;
+
+        return null != nav && 
getContext().getSearchConfiguration().getId().equals(nav.getCommandName());
+    }
+}
+


Property changes on: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/NavigationSearchCommandParameter.java
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/Restful.java
===================================================================
--- 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/Restful.java
    2008-11-18 08:54:23 UTC (rev 6946)
+++ 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/Restful.java
    2008-11-18 11:30:50 UTC (rev 6947)
@@ -1,8 +1,21 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
+* Copyright (2008) Schibsted Søk AS
+ * This file is part of SESAT.
+ *
+ *   SESAT is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Affero General Public License as published 
by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SESAT is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public License
+ *   along with SESAT.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
 package no.sesat.search.mode.command;
 
 import java.io.BufferedReader;

Added: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/SearchCommandParameter.java
===================================================================
--- 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/SearchCommandParameter.java
                             (rev 0)
+++ 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/SearchCommandParameter.java
     2008-11-18 11:30:50 UTC (rev 6947)
@@ -0,0 +1,68 @@
+/*
+* Copyright (2008) Schibsted Søk AS
+ * This file is part of SESAT.
+ *
+ *   SESAT is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Affero General Public License as published 
by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SESAT is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public License
+ *   along with SESAT.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package no.sesat.search.mode.command;
+
+/**
+ * A SearchCommandParameter are options that a search command provides to its 
users.
+ * The best two examples are the offset parameter and the userSortBy parameter.
+ * These are infact part of SearchCommand's default API. <br/>
+ *
+ * From [EMAIL PROTECTED] 
http://sesat.no/new-design-proposal-for-searchcommand-and-abstractsearchcommand.html}
  <br/> <br/>
+ *
+ * Search Command Parameters typically have three sources,
+ * and they use the first found.  <br/>
+ * For example: a url parameter, a user parameter, the command's configured 
parameter.  <br/> <br/>
+ *
+ * Sometimes (eg userSortBy and pagination) the configuration actually comes 
from the presentation layer.
+ * Here the command's configuration here must simply point to where in the 
presentation layer
+ * this configuration can be found.
+ * Strictly speaking the domain layer should be isolated from the presentation 
layer
+ * but here we access only the presentation layer's configuration through the 
datamodel. <br/> <br/>
+ *
+ * ResultToReturn is an interesting example.
+ * It should be both overridable from url and user parameters.
+ * But the configuration exist in both the presentation layer and the domain 
layer.
+ * The domain layer's only responsibility is to ensure at least the amount of 
results are returned
+ * that the presentation layer wants.
+ * Up until now its just been presumed that the command's configuration
+ * is hardcoded to a value larger than any possible presentation value.
+ *
+ * @version $Id$
+ */
+interface SearchCommandParameter{
+
+    /** The parameter name.
+     *
+     * @return the parameter name.
+     */
+    String getName();
+
+    /** Whether the parameter is active.
+     *
+     * @return true is parameter is in use.
+     */
+    boolean isActive();
+
+    /** Get the parameter's current value.
+     *
+     * @return the parameters current value. can be null is isActive() is 
false.
+     */
+    String getValue();
+}
+


Property changes on: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/SearchCommandParameter.java
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/XmlRestful.java
===================================================================
--- 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/XmlRestful.java
 2008-11-18 08:54:23 UTC (rev 6946)
+++ 
trunk/search-command-control-spi/src/main/java/no/sesat/search/mode/command/XmlRestful.java
 2008-11-18 11:30:50 UTC (rev 6947)
@@ -1,8 +1,21 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
+* Copyright (2008) Schibsted Søk AS
+ * This file is part of SESAT.
+ *
+ *   SESAT is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Affero General Public License as published 
by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SESAT is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public License
+ *   along with SESAT.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
 package no.sesat.search.mode.command;
 
 import java.io.IOException;

_______________________________________________
Kernel-commits mailing list
[email protected]
http://sesat.no/mailman/listinfo/kernel-commits

Reply via email to