pt.webdetails.cdf.dd.model.meta.reader.datasources.DataSourcesModelReader.java Source code

Java tutorial

Introduction

Here is the source code for pt.webdetails.cdf.dd.model.meta.reader.datasources.DataSourcesModelReader.java

Source

/*!
 * Copyright 2002 - 2015 Webdetails, a Pentaho company. All rights reserved.
 *
 * This software was developed by Webdetails and is provided under the terms
 * of the Mozilla Public License, Version 2.0, or any later version. You may not use
 * this file except in compliance with the license. If you need a copy of the license,
 * please go to http://mozilla.org/MPL/2.0/. The Initial Developer is Webdetails.
 *
 * Software distributed under the Mozilla Public License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
 * the license for the specific language governing your rights and limitations.
 */

package pt.webdetails.cdf.dd.model.meta.reader.datasources;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import pt.webdetails.cdf.dd.model.meta.DataSourceComponentType;
import pt.webdetails.cdf.dd.model.meta.MetaModel;
import pt.webdetails.cdf.dd.model.core.reader.ThingReadException;
import pt.webdetails.cdf.dd.util.JsonUtils;
import pt.webdetails.cpf.packager.origin.PathOrigin;
import pt.webdetails.cpf.packager.origin.OtherPluginStaticSystemOrigin;

/**
 * Loads XML model files, component types and property types, from the file system, of a Pentaho CDE plugin
 * instalation.
 *
 * @author dcleao
 */
public final class DataSourcesModelReader {
    protected static final Log logger = LogFactory.getLog(DataSourcesModelReader.class);

    public void read(MetaModel.Builder model, JSONObject cdaDefs, String sourcePath) throws ThingReadException {
        assert model != null;

        logger.info("Loading data source components of '" + sourcePath + "'");

        final JXPathContext doc;
        try {
            doc = JsonUtils.toJXPathContext(cdaDefs);
        } catch (JSONException e) {
            throw new ThingReadException("Couldn't get JXPathContext from json", e);
        }

        @SuppressWarnings("unchecked")
        Iterator<Pointer> pointers = doc.iteratePointers("*");

        while (pointers.hasNext()) {
            Pointer pointer = pointers.next();
            this.readDataSourceComponent(model, pointer, sourcePath);
        }
    }

    /**
     * @param model      where component type builders are placed
     * @param pointer
     * @param sourcePath sourcePath for all components
     */
    private void readDataSourceComponent(MetaModel.Builder model, Pointer pointer, String sourcePath) {
        // TODO: What a generality...

        DataSourceComponentType.Builder builder = new DataSourceComponentType.Builder();

        Map<String, Object> def = (Map<String, Object>) pointer.getNode();
        JXPathContext jctx = JXPathContext.newContext(def);

        String label = (String) jctx.getValue("metadata/name");

        String dataSourceType = (String) jctx.getValue("metadata/datype");

        boolean isCPK = dataSourceType.equalsIgnoreCase("cpk");
        boolean isCDA = !isCPK;

        //TODO: oh so wrong
        PathOrigin origin = new OtherPluginStaticSystemOrigin(isCPK ? "cpk" : "cda", "");
        builder.setOrigin(origin);

        // This specific Data Source has special treatment below
        boolean isKettleOverX = isCDA && "kettle over kettleTransFromFile".equalsIgnoreCase(label);

        logger.debug(String.format("\t%s", label));

        String connType = (String) jctx.getValue("metadata/conntype");
        connType = connType != null ? connType : "";

        builder.setName(pointer.asPath().replaceAll(".*name='(.*?)'.*", "$1")).setLabel(label).setTooltip(label)
                .setCategory((String) jctx.getValue("metadata/group"))
                .setCategoryLabel((String) jctx.getValue("metadata/groupdesc")).setSourcePath(sourcePath)
                .addAttribute("", isCPK ? "CPK" : "CDA"); // meta: "CDA"

        if (isCDA) {
            builder.addAttribute("conntype", connType).addAttribute("datype", dataSourceType);
        } else if (isCPK) {
            builder.useProperty(null, "stepName").useProperty(null, "kettleOutput")
                    .addAttribute("pluginId", (String) jctx.getValue("metadata/pluginId"))
                    .addAttribute("endpoint", (String) jctx.getValue("metadata/endpoint"));
        }

        if (isCDA) {
            for (String cdaPropName : this.getCDAPropertyNames(def)) {
                if (cdaPropName.equals("id") || cdaPropName.equals("connection")) {
                    continue;
                } else if (cdaPropName.equals("columns")) {
                    builder.useProperty(null, "cdacolumns");
                    builder.useProperty(null, "cdacalculatedcolumns");
                } else if (cdaPropName.equals("output")) {
                    builder.useProperty(null, "output");
                    builder.useProperty(null, "outputMode");
                } else if (cdaPropName.equals("left")) {
                    builder.useProperty(null, "left");
                    builder.useProperty(null, "leftkeys");
                } else if (cdaPropName.equals("right")) {
                    builder.useProperty(null, "right");
                    builder.useProperty(null, "rightkeys");
                } else if (isKettleOverX && cdaPropName.equalsIgnoreCase("query")) {
                    builder.useProperty(cdaPropName, "kettleQuery");
                } else {
                    builder.useProperty(null, cdaPropName);
                }
            }
        }
        model.addComponent(builder);
    }

    private List<String> getCDAPropertyNames(Map<String, Object> def) {
        ArrayList<String> props = new ArrayList<String>();

        JXPathContext context = JXPathContext.newContext(def);

        Map<String, Object> connection = (Map<String, Object>) context.getValue("definition/connection");
        if (connection != null) {
            props.addAll(connection.keySet());
        }

        Map<String, Object> dataaccess = (Map<String, Object>) context.getValue("definition/dataaccess");
        if (dataaccess != null) {
            props.addAll(dataaccess.keySet());
        }

        return props;
    }
}