001/*
002 * Copyright (c) 2004-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.ecoinformatics.seek.ecogrid.quicksearch;
031
032import java.io.StringReader;
033import java.util.Hashtable;
034import java.util.List;
035
036import javax.xml.transform.TransformerException;
037
038import org.apache.axis.types.URI;
039import org.apache.commons.logging.Log;
040import org.apache.commons.logging.LogFactory;
041import org.ecoinformatics.ecogrid.queryservice.query.QueryType;
042import org.ecoinformatics.ecogrid.queryservice.util.EcogridQueryParser;
043import org.ecoinformatics.seek.ecogrid.exception.InvalidEcogridQueryException;
044import org.kepler.configuration.ConfigurationManager;
045import org.kepler.configuration.ConfigurationProperty;
046
047/**
048 * This class will read kepler configure file and get the query part from it
049 * base on search name space.
050 * 
051 * @author Jing Tao
052 * 
053 */
054
055public class SearchQueryGenerator {
056        private String _queryId = null;
057        private Hashtable _replacementMap = null;
058        private QueryType _query = new QueryType();
059
060        private final static String QUERYPATH = "//ecogridService/queryList/query[@queryId='";
061        private final static String CONDITION = "condition";
062
063        protected final static Log log;
064        static {
065                log = LogFactory
066                                .getLog("org.ecoinformatics.seek.ecogrid.SearchQueryGenerator");
067        }
068
069        /**
070         * Constructor of SearchQueryGenerator
071         * 
072         * @param queryId
073         *            String the queryId which will be found in config
074         * @param replacementMap
075         *            Hashtable the hash table which contain the key - be replaced
076         *            value value - replacement For example, if key is "#value#",
077         *            and value is "soil". This means any element and attribute in
078         *            xml has value "#value#" will be replaced by soil
079         */
080        public SearchQueryGenerator(String queryId, Hashtable replacementMap)
081                        throws InvalidEcogridQueryException
082
083        {
084                _queryId = queryId;
085                _replacementMap = replacementMap;
086                try {
087                        generateQuery();
088                } catch (Exception e) {
089      e.printStackTrace();
090                        throw new InvalidEcogridQueryException(e.getMessage());
091                }
092        }// SearchQueryGenerator
093
094        /**
095         * Method to get query which generate by this class
096         * 
097         * @return QueryType
098         */
099        public QueryType getQuery() {
100                return _query;
101        }// getQuery
102
103        /**
104         * Recursively walks the tree looking for Condition values inorder to
105         * subsitute in the search value
106         * 
107         * @param aNode
108         *            the parent node
109         * @param aIsChildCond
110         *            indicates whether the current parent node is a Condition node
111         */
112        private void mapInValue(SearchQuery searchQuery, Hashtable aMap) 
113  {
114    searchQuery.replaceValues(aMap);
115    
116                /*NodeList childList = aNode.getChildNodes();
117                if (childList == null) 
118    {
119                        return;
120                }
121
122                // go through every child element
123                int length = childList.getLength();
124                for (int i = 0; i < length; i++) 
125    {
126                        Node kid = childList.item(i);
127      System.out.println("kid name: " + kid.getNodeName());
128                        if (kid.getNodeName().equals(CONDITION) || aIsChildCond) 
129      {
130                                String value = kid.getNodeValue();
131                                // replace the value by search value if this value in
132                                // replacementMap
133                                if (value != null && aMap.containsKey(value)) 
134        {  
135          System.out.println("replacing " + value + " with " + aMap.get(value));
136                                        log.debug("Replacing [" + value + "] with ["
137                                                        + aMap.get(value) + "]");
138                                        kid.setNodeValue((String) aMap.get(value));
139                                } 
140        else 
141        {
142                                        mapInValue(kid, true, aMap);
143                                }
144                        } 
145      else 
146      {
147                                mapInValue(kid, false, aMap);
148                        }
149                }*/
150        }
151
152        /*
153         * Method to read config file and generate a query(It will chose the first
154         * one if it has more than one in configure file)
155         */
156        private void generateQuery() throws URI.MalformedURIException,
157                        TransformerException, InvalidEcogridQueryException {
158                String xpath = QUERYPATH + _queryId + "']";
159    
160    ConfigurationProperty ecogridProperty = ConfigurationManager.getInstance()
161      .getProperty(ConfigurationManager.getModule("ecogrid"));
162    ConfigurationProperty queryPathProp = ecogridProperty.getProperty("queryList");
163    List queryList = queryPathProp.findProperties("queryId", _queryId, true);
164    if(queryList == null || queryList.size() == 0)
165    {
166      return;
167    }
168    
169    ConfigurationProperty queryProp = (ConfigurationProperty)queryList.get(0);
170    
171    SearchQuery searchQuery = new SearchQuery(queryProp);
172    
173    mapInValue(searchQuery, _replacementMap);
174
175                try {
176                        EcogridQueryParser queryParser = new EcogridQueryParser(new StringReader(searchQuery.toString()));
177                        queryParser.parseXML();
178                        _query = queryParser.getEcogridQuery();
179                } catch (Exception e) {
180      System.out.println("Error parsing query: " + e.getMessage());
181      e.printStackTrace();
182                        log.error("Exception", e);
183                }
184
185        } // generateQuery
186
187} // SearchQueryGenerator