Package com.tonbeller.jpivot.tags

Source Code of com.tonbeller.jpivot.tags.MondrianModelFactory$Config

/*
* ====================================================================
* This software is subject to the terms of the Common Public License
* Agreement, available at the following URL:
*   http://www.opensource.org/licenses/cpl.html .
* Copyright (C) 2003-2004 TONBELLER AG.
* All Rights Reserved.
* You must accept the terms of that agreement to use this software.
* ====================================================================
*
*
*/
package com.tonbeller.jpivot.tags;

import it.eng.spago.error.EMFInternalError;
import it.eng.spago.security.IEngUserProfile;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;

import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.xml.sax.SAXException;

import sun.misc.BASE64Encoder;

import com.tonbeller.jpivot.core.ModelFactory;
import com.tonbeller.jpivot.mondrian.MondrianModel;
import com.tonbeller.tbutils.res.Resources;
import com.tonbeller.wcf.controller.RequestContext;
import com.tonbeller.wcf.expr.ExprUtils;

/**
* creates a MondrianModel from config.xml
* @author av
*/
public class MondrianModelFactory {
  private static Logger logger = Logger.getLogger(MondrianModelFactory.class);

  private static final BASE64Encoder ENCODER = new BASE64Encoder();
 
  private MondrianModelFactory() {
  }

  static String makeConnectString(String filers,Config cfg, IEngUserProfile profile) {

    // for an external datasource, we do not need JdbcUrl *and* data source

    // if ((cfg.getJdbcUrl() == null) == (cfg.getDataSource() == null))
    // throw new IllegalArgumentException("exactly one of jdbcUrl or dataSource must be specified");

    // provider=Mondrian;Jdbc=jdbc:odbc:MondrianFoodMart;Catalog=file:///c:/dev/mondrian/demo/FoodMart.xml
    StringBuffer sb = new StringBuffer("provider=Mondrian");
    if (cfg.getJdbcUrl() != null) {
      String jdbcUrl = cfg.getJdbcUrl();
      sb.append(";Jdbc=");
      // if the url contains a semicolon, it must be in quotes
      if (jdbcUrl.indexOf(';') >= 0) {
        char c = jdbcUrl.charAt(0);
        if (c != '"' && c != '\'') {
          char escape = '"';
          if (jdbcUrl.indexOf('"') >= 0) {
            if (jdbcUrl.indexOf('\'') >= 0) {
              // this is not valid
              throw new IllegalArgumentException(
              "jdbcUrl is not valid - contains single and double quotes");
            }
            escape = '\'';
          }
          sb.append(escape);
          sb.append(jdbcUrl);
          sb.append(escape);
        } else
          sb.append(jdbcUrl); // already quoted
      } else
        sb.append(jdbcUrl); // no quotes neccessary

      if (cfg.getJdbcUser() != null)
        sb.append(";JdbcUser=").append(cfg.getJdbcUser());
      if (cfg.getJdbcPassword() != null && cfg.getJdbcPassword().length() > 0)
        sb.append(";JdbcPassword=").append(cfg.getJdbcPassword());
    } else if (cfg.getDataSource() != null) {
      //sb.append(";DataSource=java:comp/env/").append(cfg.getDataSource());
      sb.append(";DataSource=").append(cfg.getDataSource());
      testDataSource(cfg.getDataSource());
    }
    sb.append(";Catalog=").append(cfg.getSchemaUrl());
    /* risultato: 'provider=Mondrian;DataSource=java:comp/env/jdbc/foodmart;
     *         Catalog="file:D:/Progetti/DEMO_SPAGOBI_20/Resources/Olap/FoodMart_RoleDSP.xml"Drink;
     *         DynamicSchemaProcessor=it.eng.spagobi.jpivotaddins.roles.SpagoBIFilterDynamicSchemaProcessor;UseSchemaPool=true;
     *         family=Drink'
     * */
    /*
    try {
      sb.append(";Catalog=").append(cfg.getSchemaUrl()+profile.getUserAttribute("family"));
    } catch (EMFInternalError e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
     */
    if (cfg.getDynLocale() != null)
      sb.append(";Locale=").append(cfg.getDynLocale());

    // debug
    if (cfg.getRole() != null) {
      sb.append(";Role=").append(cfg.getRole());
    }
    if (cfg.getDataSourceChangeListener() != null) {
      sb.append(";dataSourceChangeListener=").append(cfg.getDataSourceChangeListener());
    }
    sb.append(";DynamicSchemaProcessor=it.eng.spagobi.jpivotaddins.roles.SpagoBIFilterDynamicSchemaProcessor");
    // cache control: if filtering by user profile attributes with queries inside schema definition, UseSchemaPool must be false
    //orig: sb.append(";UseSchemaPool=true");
    sb.append(";UseSchemaPool=true;UseContentChecksum=true");

    // there could be more than one attribute
    if (filers!=null){
      logger.debug("Data Access is ACTIVE!!!");
      try {
        InputStream is = new java.io.ByteArrayInputStream(filers.getBytes());
        org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();
        org.dom4j.Document document = reader.read(is)

        //org.dom4j.Node attribute = document.selectSingleNode("//DATA-ACCESS/ATTRIBUTE");
        List<Node> attributes = document.selectNodes("//DATA-ACCESS/ATTRIBUTE");
        if (attributes != null) {
          for (Iterator<Node> iterator = attributes.iterator(); iterator.hasNext();) {
            Node attribute = iterator.next();
            String attributeName = attribute.valueOf("@name");
            if (attributeName != null) {
              // if no value is found put null
              String value = profile.getUserAttribute(attributeName) != null ? profile.getUserAttribute(attributeName).toString() : null;
              logger.debug("add profile attribute "+attributeName+ " with value "+value);
              // put attribute not with filter name but with attribute name!
             
              // encoding value in Base64
              String valueBase64 = null;
              if (value != null) {
                try {
                  valueBase64 = ENCODER.encode(value.getBytes("UTF-8"));
                } catch (UnsupportedEncodingException e) {
                  logger.error("UTF-8 encoding not supported!!!!!", e);
                  valueBase64 = ENCODER.encode(value.getBytes());
                }
              }
              logger.debug("Attribute value in Base64 encoding is " + valueBase64);
              sb.append(";"+attributeName+"=" + valueBase64);           
              //sb.append(";filter=" + profile.getUserAttribute(attributeName));

            } else {
              logger.warn("Filter attribute name not found!!");
            }
          }
        } else {
          logger.warn("//DATA-ACCESS/ATTRIBUTE not found!!");
        }
      } catch (EMFInternalError e) {
        logger.error("",e);
      } catch (DocumentException e) {
        logger.error("",e);
      }
    }
    // sb.append(";Role=California manager");
    return sb.toString();
  }

  private static void testDataSource(String dataSourceName) {
    final DataSource dataSource;
    Connection connection = null;
    //String dsName = "java:comp/env/" + dataSourceName;
    String dsName = dataSourceName;
    try {
      dataSource = (DataSource) new InitialContext().lookup(dsName);
      connection = dataSource.getConnection();
    } catch (Throwable e) {
      String msg = "Datasource " + dsName + " is not configured properly";
      logger.error(msg, e);
      throw new RuntimeException(msg, e);
    } finally {
      if (connection != null)
        try {
          connection.close();
        } catch (SQLException e) {
          logger.error("could not close SQL Connection for DataSource " + dataSourceName, e);
        }
    }
  }

  public static MondrianModel instance() throws SAXException, IOException {
    URL url = MondrianModel.class.getResource("config.xml");
    return (MondrianModel) ModelFactory.instance(url);
  }

  public static MondrianModel instance(Config cfg) throws SAXException, IOException {
    URL url = MondrianModel.class.getResource("config.xml");
    return instance(null,url, cfg, null);
  }

  public static MondrianModel instance(String filers,URL url, Config cfg, IEngUserProfile profile) throws SAXException, IOException {
    if (logger.isInfoEnabled()) {
      logger.info(cfg.toString());
      logger.info("ConnectString=" + makeConnectString(filers,cfg, profile));
    }
    MondrianModel mm = (MondrianModel) ModelFactory.instance(url);
    mm.setMdxQuery(cfg.getMdxQuery());
    mm.setConnectString(makeConnectString(filers,cfg, profile));
    mm.setJdbcDriver(cfg.getJdbcDriver());
    mm.setDynresolver(cfg.getDynResolver());
    mm.setDynLocale(cfg.getDynLocale());   
    mm.setDataSourceChangeListener( cfg.getDataSourceChangeListener());

    if ("false".equalsIgnoreCase(cfg.getConnectionPooling()))
      mm.setConnectionPooling(false);
    mm.setExternalDataSource(cfg.getExternalDataSource());
    return mm;
  }

  public static class Config {
    String jdbcUrl;
    String jdbcDriver;
    String jdbcUser;
    String jdbcPassword;
    // name of datasource, i.e. "jdbc/JPivotDS"
    String dataSource;
    String schemaUrl;
    String mdxQuery;
    String role;
    String dynResolver;
    // Locale requested
    String dynLocale;

    String connectionPooling;
    // external DataSource to be used by Mondrian
    DataSource externalDataSource = null;

    String dataSourceChangeListener;

    /**
     * allows to override the current JDBC settings.
     * <p>
     * All properties are allowed
     * to contain ${some.name} that refer to other properties except the
     * dataSource attribute where ${bean.property} is interpreted as bean EL that
     * references session beans.
     * <p>
     * If a dataSource name is given, it is looked up as bean EL. If the result
     * is a DataSource, its used (e.g. the session contains a DataSource). If not,
     * its interpreted as JNDI name.
     * <p>
     * If no dataSource name is given, values for jdbcDriver etc are needed. If these
     * values are present, they are taken. Otherwise, they are looked up in the resources
     * with the keys "jdbc.driver", "jdbc.url", "jdbc.user" and "jdbc.password".
     */
    public void allowOverride(RequestContext context) {
      Resources res = context.getResources();

      // get default values
      setRole(getDefault(res, "mondrian.role", getRole()));
      setDynResolver(getDefault(res, "mondrian.dynResolver", getDynResolver()));
      setDynLocale(getDefault(res, "mondrian.dynLocale", getDynLocale()));

      setDataSourceChangeListener(getDefault(res, "mondrian.dataSourceChangeListener", getDataSourceChangeListener()));

      // if the data source is configured, use it
      if (externalDataSource != null) {
        logger.info("using external data source");
        return;
      }

      // support $-variables
      setJdbcDriver(replace(res, getJdbcDriver()));
      setJdbcUrl(replace(res, getJdbcUrl()));
      setJdbcUser(replace(res, getJdbcUser()));
      setJdbcPassword(replace(res, getJdbcPassword()));
      setConnectionPooling(replace(res, getConnectionPooling()));
      setDataSource(replace(res, getDataSource()));

      // if a data source name was given, use it
      if (!empty(dataSource)) {
        logger.info("using data source " + dataSource);
        findDataSource(context);
        return;
      }

      // if a jdbc driver was given, use it
      if (!empty(jdbcDriver)) {
        logger.info("using driver manager " + jdbcUrl);
        return;
      }

      // try default data source
      setDataSource(getDefault(res, "jdbc.datasource", getDataSource()));
      if (!empty(dataSource)) {
        logger.info("using default data source " + dataSource);
        findDataSource(context);
        return;
      }

      // try default jdbc drivermanager
      logger.info("using default driver manager " + jdbcUrl);
      setJdbcDriver(getDefault(res, "jdbc.driver", getJdbcDriver()));
      setJdbcUrl(getDefault(res, "jdbc.url", getJdbcUrl()));
      setJdbcUser(getDefault(res, "jdbc.user", getJdbcUser()));
      setJdbcPassword(getDefault(res, "jdbc.password", getJdbcPassword()));
      setConnectionPooling(getDefault(res, "jdbc.connectionPooling", getConnectionPooling()));
    }

    /**
     * tries to find a DataSource as a bean EL in the current request or session. If not
     * found, <code>dataSource</code> is interpreted as JNDI data source.
     */
    private void findDataSource(RequestContext context) {
      Object obj;
      if (ExprUtils.isExpression(dataSource)) {
        // try "${bean.dataSource}"
        obj = context.getModelReference(dataSource);
      } else {
        // try "beanName"
        obj = context.getSession().getAttribute(dataSource);
      }
      if (obj instanceof DataSource) {
        logger.info("using app dataSource " + dataSource);
        this.dataSource = null;
        this.externalDataSource = (DataSource) obj;
      }
      // otherwise use it as jndi name
    }

    /**
     * falls <code>val == null</code>, wird der default aus den resources geladen.
     * $-Variablen werden ersetzt.
     */
    private String getDefault(Resources res, String key, String val) {
      // if given, dont change
      val = replace(res, val);
      if (val != null)
        return val;
      return res.getOptionalString(key, null);
    }

    /**
     * returns null for empty strings
     */
    private String replace(Resources res, String val) {
      if (empty(val))
        return null;
      return res.replace(val);
    }

    private boolean empty(String s) {
      return s == null || s.trim().length() == 0;
    }

    /**
     * Returns the jdbcDriver.
     * @return String
     */
    public String getJdbcDriver() {
      return jdbcDriver;
    }

    /**
     * Returns the jdbcPassword.
     * @return String
     */
    public String getJdbcPassword() {
      return jdbcPassword;
    }

    /**
     * Returns the jdbcUrl.
     * @return String
     */
    public String getJdbcUrl() {
      return jdbcUrl;
    }

    /**
     * Returns the jdbcUser.
     * @return String
     */
    public String getJdbcUser() {
      return jdbcUser;
    }

    /**
     * Returns the mdxQuery.
     * @return String
     */
    public String getMdxQuery() {
      return mdxQuery;
    }

    /**
     * Returns the schemaUrl.
     * @return String
     */
    public String getSchemaUrl() {
      return schemaUrl;
    }

    /**
     * Returns the role.
     * @return String
     */
    public String getRole() {
      return role;
    }

    /**
     * Sets the role.
     * @param role The role to set
     */
    public void setRole(String role) {
      this.role = role;
    }

    /**
     * Sets the jdbcDriver.
     * @param jdbcDriver The jdbcDriver to set
     */
    public void setJdbcDriver(String jdbcDriver) {
      this.jdbcDriver = jdbcDriver;
    }

    /**
     * Sets the jdbcPassword.
     * @param jdbcPassword The jdbcPassword to set
     */
    public void setJdbcPassword(String jdbcPassword) {
      this.jdbcPassword = jdbcPassword;
    }

    /**
     * Sets the jdbcUrl.
     * @param jdbcUrl The jdbcUrl to set
     */
    public void setJdbcUrl(String jdbcUrl) {
      this.jdbcUrl = jdbcUrl;
    }

    /**
     * Sets the jdbcUser.
     * @param jdbcUser The jdbcUser to set
     */
    public void setJdbcUser(String jdbcUser) {
      this.jdbcUser = jdbcUser;
    }

    /**
     * Sets the mdxQuery.
     * @param mdxQuery The mdxQuery to set
     */
    public void setMdxQuery(String mdxQuery) {
      this.mdxQuery = mdxQuery;
    }

    /**
     * Sets the schemaUrl.
     * @param schemaUrl The schemaUrl to set
     */
    public void setSchemaUrl(String schemaUrl) {
      this.schemaUrl = schemaUrl;
    }

    /**
     * @return
     */
    public String getDataSource() {
      return dataSource;
    }

    /**
     * @param string
     */
    public void setDataSource(String string) {
      dataSource = string;
    }

    public String getDynResolver() {
      return dynResolver;
    }

    public void setDynResolver(String dynResolver) {
      this.dynResolver = dynResolver;
    }

    public String getConnectionPooling() {
      return connectionPooling;
    }

    public void setConnectionPooling(String connectionPooling) {
      this.connectionPooling = connectionPooling;
    }

    public DataSource getExternalDataSource() {
      return externalDataSource;
    }

    public void setExternalDataSource(DataSource externalDataSource) {
      this.externalDataSource = externalDataSource;
    }

    /**
     * Getter for property dynLocale.
     * @return Value of property dynLocale.
     */
    public String getDynLocale() {
      return this.dynLocale;
    }

    /**
     * Setter for property dynLocale.
     * @param dynLocale New value of property dynLocale.
     */
    public void setDynLocale(String dynLocale) {
      this.dynLocale = dynLocale;
    }

    public String toString() {
      return "Config[" + "jdbcUrl=" + jdbcUrl + ", jdbcDriver=" + jdbcDriver + ", jdbcUser="
      + jdbcUser + ", jdbcPassword=" + jdbcPassword + ", dataSource=" + dataSource
      + ", schemaUrl=" + schemaUrl + ", mdxQuery=" + mdxQuery + ", role=" + role
      + ", dynResolver=" + dynResolver + ", connectionPooling=" + connectionPooling
      + ", externalDataSource=" + externalDataSource + ", dynLocale=" + dynLocale + ", dataSourceChangeListener=" + dataSourceChangeListener + "]";
    }
    /**
     * Getter for property dataSourceChangeListener.
     * @return Value of property dataSourceChangeListener.
     */

    public String getDataSourceChangeListener() {
      return dataSourceChangeListener;
    }
    /**
     * Setter for property dataSourceChangeListener.
     * @param dataSourceChangeListener New value of property dataSourceChangeListener.
     */

    public void setDataSourceChangeListener(String dataSourceChangeListener) {
      this.dataSourceChangeListener = dataSourceChangeListener;
    }
  }
}
TOP

Related Classes of com.tonbeller.jpivot.tags.MondrianModelFactory$Config

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.