Package org.apache.oodt.xmlps.product

Source Code of org.apache.oodt.xmlps.product.XMLPSProductHandler

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.oodt.xmlps.product;

//OODT imports
import org.apache.oodt.product.ProductException;
import org.apache.oodt.product.QueryHandler;
import org.apache.oodt.xmlps.mapping.DatabaseTable;
import org.apache.oodt.xmlps.mapping.FieldScope;
import org.apache.oodt.xmlps.mapping.Mapping;
import org.apache.oodt.xmlps.mapping.MappingField;
import org.apache.oodt.xmlps.mapping.MappingReader;
import org.apache.oodt.xmlps.mapping.funcs.MappingFunc;
import org.apache.oodt.xmlps.queryparser.Expression;
import org.apache.oodt.xmlps.queryparser.HandlerQueryParser;
import org.apache.oodt.xmlps.structs.CDEResult;
import org.apache.oodt.xmlps.structs.CDEValue;
import org.apache.oodt.xmlps.util.XMLQueryHelper;
import org.apache.oodt.xmlquery.QueryElement;
import org.apache.oodt.xmlquery.XMLQuery;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* <p>
* An XML configurable version of a Product Server that requires no code
* to be written to plug into a local site's relational backend DBMS.
* </p>.
*/
public class XMLPSProductHandler implements QueryHandler {

    /* our log stream */
    private static final Logger LOG = Logger
            .getLogger(XMLPSProductHandler.class.getName());

    protected Mapping mapping;

    private DBMSExecutor executor;

    protected XMLPSProductHandler(String phony) {
        /* this is to get around invoking the default constructor in sub-classes */
    }

    public XMLPSProductHandler() throws InstantiationException {
        String MappingFilePath = System
                .getProperty("org.apache.oodt.xmlps.xml.mapFilePath");

        if (MappingFilePath == null) {
            throw new InstantiationException(
                    "Need to specify path to xml mapping file!");
        }

        try {
            mapping = MappingReader.getMapping(MappingFilePath);
        } catch (Exception e) {
            throw new InstantiationException(
                    "Unable to parse mapping xml file: ["
                            + MappingFilePath + "]: reason: "
                            + e.getMessage());
        }

        /* load the db properties file */
        /*
         * if one exists: otherwise, don't bother and just print out the SQL to
         * the console.
         */
        String dbPropFilePath = System
                .getProperty("org.apache.oodt.xmlps.xml.dbPropFilePath");
        if (dbPropFilePath != null) {
            try {
                System.getProperties()
                        .load(new FileInputStream(dbPropFilePath));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
                throw new InstantiationException(e.getMessage());
            }

            executor = new DBMSExecutor();
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see org.apache.oodt.product.QueryHandler#query(org.apache.oodt.xmlquery.XMLQuery)
     */
    public XMLQuery query(XMLQuery query) throws ProductException {
        List<QueryElement> whereSet = query.getWhereElementSet();
        List<QueryElement> selectSet = query.getSelectElementSet();
        try {
            translateToDomain(selectSet, true);
            translateToDomain(whereSet, false);
        } catch (Exception e) {
            LOG.severe(e.getMessage());
            throw new ProductException(e.getMessage());
        }

        queryAndPackageResults(query);

        return query;
    }

    public static void main(String[] args) throws Exception {
        String usage = "XMLPSProductHandler <query>\n";

        if (args.length != 1) {
            System.err.println(usage);
            System.exit(1);
        }

        XMLPSProductHandler handler = new XMLPSProductHandler();
        XMLQuery q = handler.query(XMLQueryHelper
                .getDefaultQueryFromQueryString(args[0]));
        System.out.println(q.getXMLDocString());
    }

    protected List<QueryElement> getElemNamesFromQueryElemSet(
            List<QueryElement> origSet) {
        if (origSet == null || (origSet != null && origSet.size() == 0))
            return Collections.emptyList();

        List<QueryElement> newSet = new Vector<QueryElement>();

        for (Iterator<QueryElement> i = origSet.iterator(); i.hasNext();) {
            QueryElement elem = i.next();
            if (elem.getRole().equals(XMLQueryHelper.ROLE_ELEMNAME)
                    && !mapping.constantField(elem.getValue())) {
                newSet.add(elem);

            }

        }

        return newSet;

    }

    protected List<QueryElement> getConstElemNamesFromQueryElemSet(
            List<QueryElement> origSet) {
        if (origSet == null || (origSet != null && origSet.size() == 0))
            return Collections.emptyList();

        List<QueryElement> newSet = new Vector<QueryElement>();

        for (Iterator<QueryElement> i = origSet.iterator(); i.hasNext();) {
            QueryElement elem = i.next();
            if (elem.getRole().equals(XMLQueryHelper.ROLE_ELEMNAME)
                    && mapping.constantField(elem.getValue())) {
                newSet.add(elem);
            }
        }

        return newSet;
    }

    protected void queryAndPackageResults(XMLQuery query) {
        Stack<QueryElement> queryStack = HandlerQueryParser
                .createQueryStack(query.getWhereElementSet());
        Expression parsedQuery = HandlerQueryParser.parse(queryStack,
                this.mapping);
        List<QueryElement> selectNames = getElemNamesFromQueryElemSet(query
                .getSelectElementSet());

        String querySelectNames = toSQLSelectColumns(selectNames);

        StringBuffer sqlBuf = new StringBuffer("SELECT ");
        sqlBuf.append(querySelectNames);
        sqlBuf.append(" FROM ");
        sqlBuf.append(mapping.getDefaultTable());
        sqlBuf.append(" ");

        if (mapping.getNumTables() > 0) {
            List<QueryElement> whereNames = getElemNamesFromQueryElemSet(query.getWhereElementSet());
            Set<DatabaseTable> requiredTables = getRequiredTables(whereNames, selectNames);
            for (DatabaseTable tbl : requiredTables) {
                sqlBuf.append("INNER JOIN ");
                sqlBuf.append(tbl.getName());
                sqlBuf.append(" ON ");
                sqlBuf.append(tbl.getName());
                sqlBuf.append(".");
                sqlBuf.append(tbl.getJoinFieldName());
                sqlBuf.append(" = ");
                sqlBuf.append(tbl.getDefaultTableJoin());
                sqlBuf.append(".");
                sqlBuf.append(tbl.getDefaultTableJoinFieldName());
                sqlBuf.append(" ");
            }
        }

        if(parsedQuery != null){
            sqlBuf.append(" WHERE ");
            sqlBuf.append(parsedQuery.evaluate());
        }

        LOG.log(Level.INFO, sqlBuf.toString());

        if (executor != null) {
            try {
                CDEResult res = executor.executeLocalQuery(sqlBuf.toString());
                res.setOrderedFields(query.getSelectElementSet());
                res.setMapping(mapping);
                res.setConstValues(getConstValuesForQuery(query));
                query.getResults().add(res);
            } catch (SQLException e) {
                e.printStackTrace();
                LOG.log(Level.WARNING, "Error executing sql: ["
                        + sqlBuf.toString() + "]: Message: " + e.getMessage());
            }
        }

    }

    private List<CDEValue> getConstValuesForQuery(XMLQuery query) {
        List<QueryElement> select = query.getSelectElementSet();
        List<QueryElement> constNames = getConstElemNamesFromQueryElemSet(select);
        List<CDEValue> constValues = new ArrayList<CDEValue>();
        if (constNames != null) {
            for (QueryElement qe : constNames) {
                MappingField fld = mapping.getFieldByLocalName(qe.getValue());
                if (fld != null) {
                    constValues.add(new CDEValue(fld.getName(), fld.getConstantValue()));
                }
            }
        }
        return constValues;
    }

    private String toSQLSelectColumns(List<QueryElement> elems) {
        if (elems == null || (elems != null && elems.size() == 0))
            return null;

        StringBuilder buf = new StringBuilder();
        for (QueryElement qe : elems) {
            MappingField fld = this.mapping.getFieldByLocalName(qe.getValue());
            if (fld != null) {
                buf.append(fld.getLocalName());
                buf.append(" as ");
                buf.append(fld.getName());
                buf.append(",");
            }
        }

        buf.deleteCharAt(buf.length() - 1);

        return buf.toString();
    }

    protected void translateToDomain(List<QueryElement> elemSet,
            boolean selectSet) throws Exception {
        // go through each query element: use the mapping fields
        // to translate the names

        for (Iterator<QueryElement> i = elemSet.iterator(); i.hasNext();) {
            QueryElement elem = i.next();
            if (elem.getRole().equals(XMLQueryHelper.ROLE_ELEMNAME)) {
                // do the translation
                String elemValue = elem.getValue();
                MappingField fld = this.mapping.getFieldByName(elemValue);
                // make sure fld is not null
                if (fld == null) {
                    continue;
                }

                // make sure scope is null, or if it's not null, then it's
                // FieldScope.QUERY

                if (fld.getScope() != null
                        && fld.getScope().equals(FieldScope.RETURN)) {
                    // skip
                    continue;
                }

                // check to see if it has a dbname attr, if not, then the name
                // stays
                // the same
                String newFldName = fld.getLocalName();

                elem.setValue(newFldName);

                // now translate the domain vocab if there are translate funcs
                // present and this isn't the select set

                if (!selectSet && fld.getFuncs() != null
                        && fld.getFuncs().size() > 0) {
                    // the next query element should be
                    // XMLQueryHelper.ROLE_LITERAL
                    if (!i.hasNext())
                        break;
                    QueryElement litElem = i.next();
                    if (!litElem.getRole().equals(XMLQueryHelper.ROLE_LITERAL)) {
                        throw new Exception("next query element not "
                                + XMLQueryHelper.ROLE_LITERAL + "! role is "
                                + litElem.getRole() + " instead!");
                    }

                    for (Iterator<MappingFunc> j = fld.getFuncs().iterator(); j
                            .hasNext();) {
                        MappingFunc func = j.next();
                        CDEValue origVal = new CDEValue(fld.getName(),
                                litElem.getValue());
                        CDEValue newVal = func.inverseTranslate(origVal);
                        litElem.setValue(newVal.getVal());
                    }

                }

            }
        }

    }

    protected Set<DatabaseTable> getRequiredTables(
            List<QueryElement> whereElemNames, List<QueryElement> selectElemNames) {
        Set<DatabaseTable> tables = new HashSet<DatabaseTable>();
        // add tables from where element set
        if (whereElemNames != null) {
            for (QueryElement qe : whereElemNames) {
                MappingField fld = mapping.getFieldByLocalName(qe.getValue());
                if (fld != null) {
                    DatabaseTable t = mapping.getTableByName(fld.getTableName());
                    if (t != null && !tables.contains(t) && !t.getName().equals(mapping.getDefaultTable())) {
                        tables.add(t);
                    }
                }
            }
        }
        // add tables from select element set
        if (selectElemNames != null) {
            for (QueryElement qe : selectElemNames) {
                MappingField fld = mapping.getFieldByLocalName(qe.getValue());
                if (fld != null) {
                    DatabaseTable t = mapping.getTableByName(fld.getTableName());
                    if (t != null && !tables.contains(t) && !t.getName().equals(mapping.getDefaultTable())) {
                        tables.add(t);
                    }
                }
            }
        }
        // the tables found may be joined on columns from tables we haven't found
        // yet
        // add additional required join tables
        Set<DatabaseTable> moreTables = new HashSet<DatabaseTable>(tables);
        for (DatabaseTable t : tables) {
            DatabaseTable join = mapping.getTableByName(t.getDefaultTableJoin());
            // recursively add all join tables until we get to either
            // (a) the mapping default table (join == null)
            // (b) or a table already found (moreTables.contains(join))
            while (join != null && !moreTables.contains(join) && !join.getName().equals(mapping.getDefaultTable())) {
                moreTables.add(join);
                join = mapping.getTableByName(join.getDefaultTableJoin());
            }
        }
        return moreTables;
    }

}
TOP

Related Classes of org.apache.oodt.xmlps.product.XMLPSProductHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.