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.dataquery;
031
032import java.util.Iterator;
033import java.util.List;
034
035import org.apache.commons.logging.Log;
036import org.apache.commons.logging.LogFactory;
037import org.kepler.configuration.ConfigurationManager;
038import org.kepler.configuration.ConfigurationProperty;
039
040/**
041 * This class will map delimter format in metadata (e.g eml documents) to the
042 * format in db (e.g, hsql).
043 * 
044 * @author Jing Tao
045 * 
046 */
047
048public class DelimiterResolver {
049        
050  private ConfigurationProperty sqlEngineProperty = null;
051        private String originalString;
052        private String replaceMent;
053        private static final String DELIMITERPARENTPATH = "//sqlEngine[sqlEngineName=\"hsql\"]/delimiterMapping/mapping";
054        private static final String DELIMITERPREFIXPARENTPATH = "//sqlEngine[sqlEngineName=\"hsql\"]/delimiterMapping/prefixmapping";
055        private static final String METADATADELIMITERPATH = "./metadataDelimiter";
056        private static final String DBDELIMITERPATH = "./DBdelimiter";
057
058        private static Log log;
059        private static boolean isDebugging;
060
061        static {
062                log = LogFactory.getLog("org.ecoinformatics.seek.dataquery");
063                isDebugging = log.isDebugEnabled();
064        }
065
066        /**
067         * Constructor. It will read config file and find the sepciy delimiter
068         * mapping then put them into a hash table. metadata delimiter is a key and
069         * db delimter is a value. For example, ; maps \semi. It also will read
070         * prefix mapping and metadata delimiter is a key and db delimiter is a
071         * value. For example 0x maps \\u
072         */
073        public DelimiterResolver() {
074
075    ConfigurationManager confMan = ConfigurationManager.getInstance();
076    ConfigurationProperty commonProperty = confMan.getProperty(ConfigurationManager.getModule("common"));
077    sqlEngineProperty = (ConfigurationProperty)commonProperty
078      .findProperties("sqlEngineName", "hsql", true).get(0);
079    
080        }// DelimiterResolver
081
082        /**
083         * This method will figure out a db delimiter when given a metadata
084         * delimiter. If metadataDelimiter is null, null will be returned. Here is
085         * way: 1. If the given metadataDelimiter is in the special hash (read from
086         * config file), the mapping will return from the hash. 2. If the given
087         * metadataDelimter is start with a prefix mapping, the mapping value will
088         * replaced by mapping key. for example a hexademical number start with
089         * "0x", (e.g. 0x##), the mapping to "0x" is "\\u", so "\\u##" will be
090         * returned. 3. The others will return itself(the given metadataDelimiter)
091         * 
092         * @param metadataDelimiter
093         *            String
094         * @return String
095         */
096        public String resolve(String metadataDelimiter) {
097                String dbDelimiter = null;
098                if (metadataDelimiter == null) {
099                        if (isDebugging) {
100                                log.debug("The dbDelimiter is " + dbDelimiter);
101                        }
102                        return dbDelimiter;
103                }
104
105                if (sqlEngineProperty != null) 
106    {
107                        //dbDelimiter = (String) specialMapping.get(metadataDelimiter);
108      if(metadataDelimiter.equals("\t"))
109      {
110        metadataDelimiter = "tab";
111      }
112      else if(metadataDelimiter.equals(" "))
113      {
114        metadataDelimiter = "space";
115      }
116      
117      List l = sqlEngineProperty.findProperties("metadataDelimiter", metadataDelimiter, true);
118      ConfigurationProperty mappingProperty;
119      if(l.size() > 0)
120      {
121        mappingProperty = (ConfigurationProperty)l.get(0);
122        dbDelimiter = mappingProperty.getProperty("DBdelimiter").getValue();
123      }
124      else
125      {
126        dbDelimiter = metadataDelimiter;
127      }
128      
129                } else if (startWithPrefix(metadataDelimiter)) {
130                        if (replaceMent != null && originalString != null) {
131                                dbDelimiter = replaceMent
132                                                + metadataDelimiter.substring(originalString.length());
133                        } else {
134                                throw new RuntimeException(
135                                                "The mapping values for delimiter prefix is null");
136                        }
137                } else {
138                        dbDelimiter = metadataDelimiter;
139                }
140                if (isDebugging) {
141                        log.debug("The dbDelimiter is " + dbDelimiter);
142                }
143                return dbDelimiter;
144        }// resolve
145
146        /*
147         * For a given delimiter, this method will see if it start with a prefix
148         * replacement
149         */
150        private boolean startWithPrefix(String givenDelimiter) {
151                boolean inHash = false;
152                if (sqlEngineProperty != null && givenDelimiter != null) {
153                        //Iterator enm = specialPrefixMapping.keySet().iterator();
154      List prefixes = sqlEngineProperty.getProperties("delimiterMapping.prefixmapping"); 
155                        // go through the hash table to if the givenDelimiter start with a
156                        // prefix
157      Iterator enm = prefixes.iterator();
158                        while (enm.hasNext()) {
159                                //String prefix = (String) enm.next();
160        ConfigurationProperty prefixMapping = (ConfigurationProperty)enm.next();
161        String prefix = prefixMapping.getProperty("metadataDelimiter").getValue();
162                                if (prefix != null && givenDelimiter.startsWith(prefix)) {
163                                        inHash = true;
164                                        originalString = prefix;
165                                        //replaceMent = (String) specialPrefixMapping.get(prefix);
166          replaceMent = prefixMapping.getProperty("DBdelimiter").getValue();
167                                        break;
168                                }
169                        }
170                }
171                return inHash;
172        }// startWithPrefix
173
174}