Package org.jasig.portal

Source Code of org.jasig.portal.RDBMChannelRegistryStore

/* Copyright 2001, 2002 The JA-SIG Collaborative.  All rights reserved.
*  See license distributed with this file and
*  available online at http://www.uportal.org/license.html
*/

package org.jasig.portal;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pluto.om.common.Preference;
import org.apache.pluto.om.common.PreferenceSet;
import org.jasig.portal.channels.portlet.CPortletAdapter;
import org.jasig.portal.container.om.common.PreferenceSetImpl;
import org.jasig.portal.groups.GroupsException;
import org.jasig.portal.groups.IEntity;
import org.jasig.portal.groups.IEntityGroup;
import org.jasig.portal.groups.IGroupMember;
import org.jasig.portal.groups.ILockableEntityGroup;
import org.jasig.portal.i18n.LocaleManager;
import org.jasig.portal.properties.PropertiesManager;
import org.jasig.portal.rdbm.DatabaseMetaDataImpl;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.services.EntityCachingService;
import org.jasig.portal.services.GroupService;
import org.jasig.portal.tools.versioning.VersionsManager;
import org.jasig.portal.utils.CounterStoreFactory;

/**
* Reference implementation of IChannelRegistryStore.
* @author Ken Weiner, kweiner@unicon.net
* @version $Revision: 1.87 $
*/
public class RDBMChannelRegistryStore implements IChannelRegistryStore {

    private static final Log log = LogFactory.getLog(RDBMChannelRegistryStore.class);

  /**
   * Add join queries for databases that are known to support them
   */
  static {
    try {
      if (RDBMServices.getDbMetaData().supportsOuterJoins()) {
        if (RDBMServices.getDbMetaData().getJoinQuery() instanceof DatabaseMetaDataImpl.JdbcDb) {
          RDBMServices.getDbMetaData().getJoinQuery().addQuery("channel",
            "{oj UP_CHANNEL UC LEFT OUTER JOIN UP_CHANNEL_PARAM UCP ON UC.CHAN_ID = UCP.CHAN_ID} WHERE");
        } else if (RDBMServices.getDbMetaData().getJoinQuery() instanceof DatabaseMetaDataImpl.PostgreSQLDb) {
           RDBMServices.getDbMetaData().getJoinQuery().addQuery("channel",
            "UP_CHANNEL UC LEFT OUTER JOIN UP_CHANNEL_PARAM UCP ON UC.CHAN_ID = UCP.CHAN_ID WHERE");
       } else if (RDBMServices.getDbMetaData().getJoinQuery() instanceof DatabaseMetaDataImpl.OracleDb) {
          RDBMServices.getDbMetaData().getJoinQuery().addQuery("channel",
            "UP_CHANNEL UC, UP_CHANNEL_PARAM UCP WHERE UC.CHAN_ID = UCP.CHAN_ID(+) AND");
        } else {
          throw new Exception("Unknown database driver");
        }
      }
    } catch (Exception e) {
      log.error( "RDBMChannelRegistryStore: Error in static initializer", e);
    }
  }

  // I18n property
  protected static final boolean localeAware = PropertiesManager.getPropertyAsBoolean("org.jasig.portal.i18n.LocaleManager.locale_aware", LocaleManager.DEFAULT_LOCALE_AWARE);
 
  /**
   * Create a new ChannelType object.
   * @return channelType, the new channel type
   * @throws java.lang.Exception
   */
  public ChannelType newChannelType() throws Exception {
    int nextChanTypeId = CounterStoreFactory.getCounterStoreImpl().getIncrementIntegerId("UP_CHAN_TYPE");
    return new ChannelType(nextChanTypeId);
  }

  /**
   * Get the channel type associated with a particular identifier.
   * @param channelTypeId the channel type identifier
   * @return channelType the channel type
   * @throws java.sql.SQLException
   */
  public ChannelType getChannelType(int channelTypeId) throws SQLException {
    ChannelType channelType = null;
    Connection con = RDBMServices.getConnection();

    try {
      Statement stmt = con.createStatement();
      try {
        String query = "SELECT * FROM UP_CHAN_TYPE WHERE TYPE_ID=" + channelTypeId;
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.getChannelType(): " + query);
        ResultSet rs = stmt.executeQuery(query);
        try {
          if (rs.next()) {
            String javaClass = rs.getString("TYPE");
            String name = rs.getString("TYPE_NAME");
            String descr = rs.getString("TYPE_DESCR");
            String cpdUri = rs.getString("TYPE_DEF_URI");

            channelType = new ChannelType(channelTypeId);
            channelType.setJavaClass(javaClass);
            channelType.setName(name);
            channelType.setDescription(descr);
            channelType.setCpdUri(cpdUri);
          }
        } finally {
          rs.close();
        }
      } finally {
        stmt.close();
      }
    } finally {
      RDBMServices.releaseConnection(con);
    }
    return channelType;
  }

  /**
   * Get channel types.
   * @return types, the channel types
   * @throws java.sql.SQLException
   */
  public ChannelType[] getChannelTypes() throws SQLException {
    ChannelType[] channelTypes = null;
    Connection con = RDBMServices.getConnection();

    try {
      Statement stmt = con.createStatement();
      try {
        String query = "SELECT TYPE_ID, TYPE, TYPE_NAME, TYPE_DESCR, TYPE_DEF_URI FROM UP_CHAN_TYPE";
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.getChannelTypes(): " + query);
        ResultSet rs = stmt.executeQuery(query);
        try {
          List channelTypesList = new ArrayList();
          while (rs.next()) {
            int channelTypeId = rs.getInt(1);
            String javaClass = rs.getString(2);
            String name = rs.getString(3);
            String descr = rs.getString(4);
            String cpdUri = rs.getString(5);

            ChannelType channelType = new ChannelType(channelTypeId);
            channelType.setJavaClass(javaClass);
            channelType.setName(name);
            channelType.setDescription(descr);
            channelType.setCpdUri(cpdUri);
            channelTypesList.add(channelType);
          }
          channelTypes = (ChannelType[])channelTypesList.toArray(new ChannelType[0]);
        } finally {
          rs.close();
        }
      } finally {
        stmt.close();
      }
    } finally {
      RDBMServices.releaseConnection(con);
    }
    return channelTypes;
  }

  /**
   * Persists a channel type.
   * @param chanType a channel type
   * @throws java.sql.SQLException
   */
  public void saveChannelType(ChannelType chanType) throws SQLException {
    Connection con = null;

    // Check if channel type exists.  If it doesn't exist, do an insert.
    // Otherwise, do an update.
    ChannelType chanTypeInStore = getChannelType(chanType.getId());
    int chanTypeId = chanType.getId();
    String javaClass = chanType.getJavaClass();
    String name = chanType.getName();
    String descr = chanType.getDescription();
    String cpdUri = chanType.getCpdUri();
    con = RDBMServices.getConnection();

    if (chanTypeInStore == null) {
        try {
            String insert = "INSERT INTO UP_CHAN_TYPE VALUES (" +
            "?, ?, ?, ?, ?)";
            PreparedStatement pstmt = con.prepareStatement(insert);
          try {
              pstmt.setInt(1, chanTypeId);
              pstmt.setString(2, javaClass);
              pstmt.setString(3, name);
              pstmt.setString(4, descr);
              pstmt.setString(5, cpdUri);

              if (log.isDebugEnabled())
                  log.debug("Save Channel Type SQL('" + chanTypeId + "', " +
                      "'" + javaClass + "', " + "'" + name + "', " +
                      "'" + descr + "', " + "'" + cpdUri + "'): " + insert );
              pstmt.executeUpdate();
          } catch (SQLException sqle) {
              // Roll back the transaction
              RDBMServices.rollback(con);
              throw sqle;
          } finally {
            pstmt.close();
          }
      } finally {
        RDBMServices.releaseConnection(con);
      }
    } else {
      // The channel type exists, so do an update
      try {
        String update = "UPDATE UP_CHAN_TYPE SET TYPE=?, TYPE_NAME=?, " +
                "TYPE_DESCR=?, TYPE_DEF_URI=? WHERE TYPE_ID=?";
        PreparedStatement pstmt = con.prepareStatement(update);
        try {
            pstmt.setString(1, javaClass);
            pstmt.setString(2, name);
            pstmt.setString(3, descr);
            pstmt.setString(4, cpdUri);
            pstmt.setInt(5, chanTypeId);
            if (log.isDebugEnabled())
                log.debug("Save Channel Type SQL('" + javaClass + "', " +
                    "'" + name + "', " + "'" + descr + "', " +
                    "'" + cpdUri + "'" + chanTypeId + "', " +
                    "'): " + update );
            pstmt.executeUpdate();
        } catch (SQLException sqle) {
          // Roll back the transaction
          RDBMServices.rollback(con);
          throw sqle;
        } finally {
            pstmt.close();
        }
      } finally {
        RDBMServices.releaseConnection(con);
      }
    }
  }

  /**
   * Deletes a channel type.  The deletion will only succeed if no existing
   * channels reference the channel type.
   * @param chanType a channel type
   * @throws java.sql.SQLException
   */
  public void deleteChannelType(ChannelType chanType) throws SQLException {
    Connection con = null;

    try {
      con = RDBMServices.getConnection();

      // Set autocommit false for the connection
      RDBMServices.setAutoCommit(con, false);
      Statement stmt = con.createStatement();

      try {
        // First check to see if any channels are still referencing this channel type
        int chanTypeId = chanType.getId();
        String select = "SELECT * FROM UP_CHANNEL WHERE CHAN_TYPE_ID=" + chanTypeId;
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.deleteChannelType(): " + select);
        ResultSet rs = stmt.executeQuery(select);

        // If there are channels referencing this channel type, throw an exception
        if (rs.next()) {
          String message = "Cannot delete channel type " + chanTypeId + ".  It is still in use by channels ";
          do {
            int channelPublishId = rs.getInt("CHAN_ID");
            message += channelPublishId + " ";
          } while (rs.next());
          throw new SQLException(message);
        // Otherwise delete the channel type
        } else {
          String delete = "DELETE FROM UP_CHAN_TYPE WHERE TYPE_ID=" + chanTypeId;
          if (log.isDebugEnabled())
              log.debug("RDBMChannelRegistryStore.deleteChannelType(): " + delete);
          int rows = stmt.executeUpdate(delete);
        }

        // Commit the transaction
        RDBMServices.commit(con);
      } catch (SQLException sqle) {
        // Roll back the transaction
        RDBMServices.rollback(con);
        throw sqle;
      } finally {
          stmt.close();
      }
    } finally {
      RDBMServices.releaseConnection(con);
    }
  }

  /**
   * Create a new ChannelDefinition object.
   * @return channelDefinition, the new channel definition
   * @throws java.lang.Exception
   */
  public ChannelDefinition newChannelDefinition() throws Exception {
    int nextChanDefId = CounterStoreFactory.getCounterStoreImpl().getIncrementIntegerId("UP_CHANNEL");
    return new ChannelDefinition(nextChanDefId);
  }

  /**
   * Get a channel definition.
   * @param channelPublishId a channel publish ID
   * @return channelDefinition, a definition of the channel or <code>null</code>
   *   if no matching channel definition can be found
   * @throws java.sql.SQLException
   */
  public ChannelDefinition getChannelDefinition(int channelPublishId) throws SQLException {
    ChannelDefinition channelDef = null;

    // Check the cache
    try {
      channelDef = (ChannelDefinition)EntityCachingService.instance().get(ChannelDefinition.class, String.valueOf(channelPublishId));
    } catch (Exception e) {
      log.error("Error checking cache for definition of channel with publish id "
              + channelPublishId, e);
    }

    // If not found in cache, get it from the store and cache it, otherwise return it
    if (channelDef == null) {
      Connection con = null;
      PreparedStatement pstmtChannel = null;
      PreparedStatement pstmtChannelParam = null;
      PreparedStatement pstmtChannelMdata = null;
      ResultSet rs = null;

      try {
        con = RDBMServices.getConnection();
        pstmtChannel = getChannelPstmt(con);
        pstmtChannelParam = getChannelParamPstmt(con);
        pstmtChannelMdata = getChannelMdataPstmt(con);
        pstmtChannel.clearParameters();
        pstmtChannel.setInt(1, channelPublishId);
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.getChannelDefinition(): " +
                    pstmtChannel);
        rs = pstmtChannel.executeQuery();

        if (rs.next()) {
          int chanType = rs.getInt(4);
          if (rs.wasNull()) {
            chanType = 0;
          }
          int publisherId = rs.getInt(5);
          if (rs.wasNull()) {
             publisherId = 0;
          }
          int approverId = rs.getInt(6);
          if (rs.wasNull()) {
            approverId = 0;
          }
          int timeout = rs.getInt(9);
          if (rs.wasNull()) {
            timeout = 0;
          }
          channelDef = new ChannelDefinition(channelPublishId);
          channelDef.setTitle(rs.getString(1));
          channelDef.setDescription(rs.getString(2));
          channelDef.setJavaClass(rs.getString(3));
          channelDef.setTypeId(chanType);
          channelDef.setPublisherId(publisherId);
          channelDef.setApproverId(approverId);
          channelDef.setPublishDate(rs.getTimestamp(7));
          channelDef.setApprovalDate(rs.getTimestamp(8));
          channelDef.setTimeout(timeout);
          channelDef.setEditable(RDBMServices.dbFlag(rs.getString(10)));
          channelDef.setHasHelp(RDBMServices.dbFlag(rs.getString(11)));
          channelDef.setHasAbout(RDBMServices.dbFlag(rs.getString(12)));
          channelDef.setName(rs.getString(13));
          channelDef.setFName(rs.getString(14));
          channelDef.setIsSecure(RDBMServices.dbFlag(rs.getString(15)));

          // Don't use the following line to attain DB compatibility
          // channelDef.setLocale("en_US");

          int dbOffset = 0;
          if (pstmtChannelParam == null) { // we are using a join statement so no need for a new query
            dbOffset = 15;
          } else {
            rs.close();
            pstmtChannelParam.clearParameters();
            pstmtChannelParam.setInt(1, channelPublishId);
            if (log.isDebugEnabled())
                log.debug("RDBMChannelRegistryStore.getChannelDefinition(): " +
                        pstmtChannelParam);
            rs = pstmtChannelParam.executeQuery();
          }

          while (true) {
            if (pstmtChannelParam != null && !rs.next()) {
              break;
            }
            String name = rs.getString(dbOffset + 1);
            String value = rs.getString(dbOffset + 2);
            String override = rs.getString(dbOffset + 3);
            if (name != null) {
              channelDef.addParameter(name, value, override);
            }
            if (pstmtChannelParam == null && !rs.next()) {
              break;
            }
          }

          IPortletPreferencesStore portletPrefStore = PortletPreferencesStoreFactory.getPortletPreferencesStoreImpl();
          PreferenceSet preferences = null;
          try {
              preferences = portletPrefStore.getDefinitionPreferences(channelPublishId);
          }
          catch (Exception e) {
              log.error(e,e);
              preferences = null;
          }
          if (preferences != null){
            for (Iterator prefItr = preferences.iterator(); prefItr.hasNext();) {
                Preference pref = (Preference)prefItr.next();
 
                String name = pref.getName();
                String value = "";
                String override;
 
                if (pref.isReadOnly()) {
                    override = "N";
                }
                else {
                    override = "Y";
                }
 
                //Since publish params only support single valued params just look for the first value.
                Iterator valuesItr = pref.getValues();
                if (valuesItr.hasNext())
                    value = (String)valuesItr.next();
 
                channelDef.addParameter(CPortletAdapter.portletPreferenceNamePrefix + name, value, override);
            }
          }

          if (localeAware) {
              // Read UP_CHANNEL_MDATA
              rs.close();
              pstmtChannelMdata.clearParameters();
              pstmtChannelMdata.setInt(1, channelPublishId);
              if (log.isDebugEnabled())
                  log.debug("RDBMChannelRegistryStore.getChannelDefinition(): " +
                          pstmtChannelMdata);
              try {
                  rs = pstmtChannelMdata.executeQuery();

                  String locale;
                  while (true) {
                      if (pstmtChannelMdata != null && !rs.next()) {
                          break;
                      }
                      locale = rs.getString(1);
                      channelDef.putChanTitles(locale, rs.getString(2));
                      channelDef.putChanDescs(locale, rs.getString(3));
                      channelDef.putChanNames(locale, rs.getString(4));

                      if (pstmtChannelMdata == null && !rs.next()) {
                          break;
                      }
                  }
              }  catch (SQLException e) {
                  log.error( "RDBMChannelRegistryStore.getChannelDefinition(): Database being used is not internationalized. Execute `ant i18n-db' for internationalized database setting.");
              }
          }
        }

        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.getChannelDefinition(): Read channel " +
                    channelPublishId + " from the store");

        // Add the channel definition to the cache
        try {
          EntityCachingService.instance().add(channelDef);
        } catch (Exception e) {
          log.error("Error caching channel definition " + channelDef, e);
        }

      } finally {
          try { rs.close(); } catch (Exception e) {}
          try { pstmtChannel.close(); } catch (Exception e) {}
          try { pstmtChannelParam.close(); } catch (Exception e) {}
          try { pstmtChannelMdata.close(); } catch (Exception e) {}
          try { RDBMServices.releaseConnection(con); } catch (Exception e) {}
      }
    }
    return channelDef;
  }

  /**
   * Get a channel definition.  If there is more than one channel definition
   * with the given functional name, then the one with the most recent
   * approval date will be returned.
   * @param channelFunctionalName a channel functional name
   * @return channelDefinition, a definition of the channel or <code>null</code>
   *   if no matching channel definition can be found
   * @throws java.sql.SQLException
   */
  public ChannelDefinition getChannelDefinition(String channelFunctionalName) throws SQLException {
    ChannelDefinition channelDef = null;
    Connection con = RDBMServices.getConnection();

    try {
        String query = "SELECT CHAN_ID FROM UP_CHANNEL WHERE CHAN_FNAME=? ORDER BY CHAN_APVL_DT DESC";
        PreparedStatement pstmt = con.prepareStatement(query);
      try {
        if (log.isDebugEnabled())
            log.debug("Executing '" + query + "' with CHAN_FNAME=" +
                    channelFunctionalName);
       
        pstmt.setString(1, channelFunctionalName);
        ResultSet rs = pstmt.executeQuery();
        try {
          if (rs.next()) {
            channelDef = getChannelDefinition(rs.getInt("CHAN_ID"));
          }
        } finally {
          rs.close();
        }
      } finally {
        pstmt.close();
      }
    } finally {
      RDBMServices.releaseConnection(con);
    }
    return channelDef;
  }

  /**
   * Get all channel definitions including ones that haven't been approved.
   * @return channelDefs, the channel definitions
   * @throws java.sql.SQLException
   */
  public ChannelDefinition[] getChannelDefinitions() throws SQLException {
    ChannelDefinition[] channelDefs = null;
    Connection con = RDBMServices.getConnection();

    try {
      Statement stmt = con.createStatement();
      try {
        String query = "SELECT CHAN_ID FROM UP_CHANNEL";
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.getChannelDefinitions(): " + query);
        ResultSet rs = stmt.executeQuery(query);
        try {
          List channelDefsList = new ArrayList();
          while (rs.next()) {
            ChannelDefinition channelDef = getChannelDefinition(rs.getInt("CHAN_ID"));
            channelDefsList.add(channelDef);
          }
          channelDefs = (ChannelDefinition[])channelDefsList.toArray(new ChannelDefinition[0]);
        } finally {
          rs.close();
        }
      } finally {
        stmt.close();
      }
    } finally {
      RDBMServices.releaseConnection(con);
    }
    return channelDefs;
  }

  /**
   * Persists a channel definition.
   * @param channelDef the channel definition
   * @throws java.sql.SQLException
   */
  public void saveChannelDefinition (ChannelDefinition channelDef) throws Exception {
    Connection con = RDBMServices.getConnection();
    try {
      int channelPublishId = channelDef.getId();

      // Set autocommit false for the connection
      RDBMServices.setAutoCommit(con, false);
      Statement stmt = con.createStatement();
      try {
        String sqlTitle = RDBMServices.sqlEscape(channelDef.getTitle());
        String sqlDescription = RDBMServices.sqlEscape(channelDef.getDescription());
        String sqlClass = channelDef.getJavaClass();
        int sqlTypeID = channelDef.getTypeId();
        int chanPublisherId = channelDef.getPublisherId();
        String chanPublishDate = RDBMServices.getDbMetaData().sqlTimeStamp(channelDef.getPublishDate());
        int chanApproverId = channelDef.getApproverId();
        String chanApprovalDate = RDBMServices.getDbMetaData().sqlTimeStamp(channelDef.getApprovalDate());
        int sqlTimeout = channelDef.getTimeout();
        String sqlEditable = RDBMServices.dbFlag(channelDef.isEditable());
        String sqlHasHelp = RDBMServices.dbFlag(channelDef.hasHelp());
        String sqlHasAbout = RDBMServices.dbFlag(channelDef.hasAbout());
        String sqlName = RDBMServices.sqlEscape(channelDef.getName());
        String sqlFName = RDBMServices.sqlEscape(channelDef.getFName());
        String sqlIsSecure = RDBMServices.dbFlag(channelDef.isSecure());

        String query = "SELECT CHAN_ID FROM UP_CHANNEL WHERE CHAN_ID=" + channelPublishId;
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.saveChannelDefinition(): " + query);
        ResultSet rs = stmt.executeQuery(query);

        // If channel is already there, do an update, otherwise do an insert
        if (rs.next()) {
          String update = "UPDATE UP_CHANNEL SET " +
          "CHAN_TITLE='" + sqlTitle + "', " +
          "CHAN_DESC='" + sqlDescription + "', " +
          "CHAN_CLASS='" + sqlClass + "', " +
          "CHAN_TYPE_ID=" + sqlTypeID + ", " +
          "CHAN_PUBL_ID=" + chanPublisherId + ", " +
          "CHAN_PUBL_DT=" + chanPublishDate + ", " +
          "CHAN_APVL_ID=" + chanApproverId + ", " +
          "CHAN_APVL_DT=" + chanApprovalDate + ", " +
          "CHAN_TIMEOUT=" + sqlTimeout + ", " +
          "CHAN_EDITABLE='" + sqlEditable + "', " +
          "CHAN_HAS_HELP='" + sqlHasHelp + "', " +
          "CHAN_HAS_ABOUT='" + sqlHasAbout + "', " +
          "CHAN_NAME='" + sqlName + "', " +
          "CHAN_FNAME='" + sqlFName + "', " +
          "CHAN_SECURE='" + sqlIsSecure + "' " +
          "WHERE CHAN_ID=" + channelPublishId;
          if (log.isDebugEnabled())
              log.debug("RDBMChannelRegistryStore.saveChannelDefinition(): " + update);
          stmt.executeUpdate(update);
        } else {
          String insert = "INSERT INTO UP_CHANNEL (CHAN_ID, CHAN_TITLE, CHAN_DESC, CHAN_CLASS, CHAN_TYPE_ID, CHAN_PUBL_ID, CHAN_PUBL_DT, "
              + "CHAN_APVL_ID, CHAN_APVL_DT, CHAN_TIMEOUT, CHAN_EDITABLE, CHAN_HAS_HELP, CHAN_HAS_ABOUT, CHAN_NAME, CHAN_FNAME, CHAN_SECURE) ";
          insert += "VALUES (" + channelPublishId + ", '" + sqlTitle + "', '" + sqlDescription + "', '" + sqlClass + "', " + sqlTypeID + ", "
              + chanPublisherId + ", " + chanPublishDate + ", " + chanApproverId + ", " + chanApprovalDate + ", " + sqlTimeout
              + ", '" + sqlEditable + "', '" + sqlHasHelp + "', '" + sqlHasAbout
              + "', '" + sqlName + "', '" + sqlFName + "', '" + sqlIsSecure + "')";
          if (log.isDebugEnabled())
              log.debug("RDBMChannelRegistryStore.saveChannelDefinition(): " + insert);
          stmt.executeUpdate(insert);
        }

        // First delete existing parameters for this channel
        String delete = "DELETE FROM UP_CHANNEL_PARAM WHERE CHAN_ID=" + channelPublishId;
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.saveChannelDefinition(): " + delete);
        int recordsDeleted = stmt.executeUpdate(delete);

        ChannelParameter[] parameters = channelDef.getParameters();

        if (parameters != null) {
          // Keep track of any portlet preferences
          PreferenceSetImpl preferences = new PreferenceSetImpl();

          for (int i = 0; i < parameters.length; i++) {
            String paramName = parameters[i].getName();
            String paramValue = parameters[i].getValue();
            boolean paramOverride = parameters[i].getOverride();

            if (paramName == null && paramValue == null) {
              throw new RuntimeException("Invalid parameter node");
            }

            if (paramName.startsWith(CPortletAdapter.portletPreferenceNamePrefix)) {
                // We have a portlet preference
                String prefName = paramName.substring(CPortletAdapter.portletPreferenceNamePrefix.length());
                String prefValue = paramValue;
                List prefValues = (List)preferences.get(prefName);
                // Unfortunately, we can only support single-valued preferences
                // at this level unless we change a lot of uPortal code :(
                prefValues = new ArrayList(1);
                prefValues.add(prefValue);
                preferences.add(prefName, prefValues, !paramOverride);
            } else {
                // We have a normal channel parameter
                String insert = "INSERT INTO UP_CHANNEL_PARAM (CHAN_ID, CHAN_PARM_NM, CHAN_PARM_VAL, CHAN_PARM_OVRD) VALUES (" + channelPublishId +
                                ",'" + paramName + "','" + paramValue + "', '" + (paramOverride ? "Y" : "N") + "')";
                if (log.isDebugEnabled())
                    log.debug("RDBMChannelRegistryStore.saveChannelDefinition(): " + insert);
                stmt.executeUpdate(insert);
            }
          }
          if (preferences.size() > 0) {
              PortletPreferencesStoreFactory.getPortletPreferencesStoreImpl().setDefinitionPreferences(channelPublishId, preferences);
          }
        }

        // Commit the transaction
        RDBMServices.commit(con);

        // Notify the cache
        try {
          EntityCachingService.instance().update(channelDef);
        } catch (Exception e) {
          log.error("Error updating cache for channel definition " + channelDef, e);
        }

      } catch (SQLException sqle) {
        log.error("Exception saving channel definition " + channelDef, sqle);
        RDBMServices.rollback(con);
        throw sqle;
      } finally {
        stmt.close();
      }
    } finally {
      RDBMServices.releaseConnection(con);
    }
  }

  /**
   * Permanently deletes a channel definition from the store.
   * All references to this channel definition are also deleted.
   * @param channelDef the channel definition
   * @throws java.sql.SQLException
   * @throws org.jasig.portal.groups.GroupsException
   */
  public void deleteChannelDefinition(ChannelDefinition channelDef) throws SQLException, GroupsException {
    Connection con = RDBMServices.getConnection();
    try {
      Statement stmt = con.createStatement();
      try {
        int channelPublishId = channelDef.getId();

        // Remove versioning information for channel if found.
        VersionsManager mgr = VersionsManager.getInstance();
        mgr.removeVersion(channelDef.getFName());

        // Delete from UP_CHANNEL
        String delete = "DELETE FROM UP_CHANNEL WHERE CHAN_ID=" + channelPublishId;
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.deleteChannelDefinition(): " + delete);
        stmt.executeUpdate(delete);

        // Delete from UP_CHANNEL_PARAM
        delete = "DELETE FROM UP_CHANNEL_PARAM WHERE CHAN_ID=" + channelPublishId;
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.deleteChannelDefinition(): " + delete);
        stmt.executeUpdate(delete);

        // Delete from UP_PERMISSION
        // This needs to be updated to work with permission interfaces!!!
        delete = "DELETE FROM UP_PERMISSION WHERE OWNER='CHAN_ID." + channelPublishId + "' OR TARGET='CHAN_ID." + channelPublishId + "'";
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.deleteChannelDefinition(): " + delete);
        stmt.executeUpdate(delete);

        // Delete from UPC_KEYWORD
        delete = "DELETE FROM UPC_KEYWORD WHERE CHAN_ID=" + channelPublishId;
        if (log.isDebugEnabled())
            log.debug("RDBMChannelRegistryStore.deleteChannelDefinition(): " + delete);
        stmt.executeUpdate(delete);

        // Disassociate from parent categories (delete from UP_GROUP_MEMBERSHIP)
        IEntity channelDefEntity = GroupService.getEntity(String.valueOf(channelPublishId), ChannelDefinition.class);
        Iterator iter = channelDefEntity.getContainingGroups();
        while (iter.hasNext()) {
          IEntityGroup parentGroup = (IEntityGroup)iter.next();
          parentGroup.removeMember(channelDefEntity);
          parentGroup.updateMembers();
        }

        // Notify the cache
        try {
          EntityCachingService.instance().remove(channelDef);
        } catch (Exception e) {
          log.error("Error removing channel definition "
                  + channelDef + " from cache.", e);
        }

      } finally {
        stmt.close();
      }
    } finally {
      RDBMServices.releaseConnection(con);
    }
  }

  /**
   * Sets a channel definition as "approved".  This effectively makes a
   * channel definition available in the channel registry, making the channel
   * available for subscription to those authorized to subscribe to it.
   * This method is a convenience method. As an alternative to calling
   * this method, one could simply set the approver ID and approval date
   * and then call saveChannelDefinition(ChannelDefinition chanDef).
   * @param channelDef the channel definition to approve
   * @param approver the user that approves this channel definition
   * @param approveDate the date when the channel definition should be approved (can be future dated)
   * @throws Exception
   */
  public void approveChannelDefinition(ChannelDefinition channelDef, IPerson approver, Date approveDate) throws Exception {
    channelDef.setApproverId(approver.getID());
    channelDef.setApprovalDate(approveDate);
    saveChannelDefinition(channelDef);
  }

  /**
   * Removes a channel from the channel registry by changing
   * its status from "approved" to "unapproved".  Afterwards, no one
   * will be able to subscribe to or render the channel.
   * This method is a convenience method. As an alternative to calling
   * this method, one could simply set the approver ID and approval date
   * to NULL and then call saveChannelDefinition(ChannelDefinition chanDef).
   * @param channelDef the channel definition to disapprove
   * @throws Exception
   */
  public void disapproveChannelDefinition(ChannelDefinition channelDef) throws Exception {
    channelDef.setApproverId(-1);
    channelDef.setApprovalDate(null);
    saveChannelDefinition(channelDef);
  }

  /**
   * Creates a new channel category.
   * @return channelCategory the new channel category
   * @throws org.jasig.portal.groups.GroupsException
   */
  public ChannelCategory newChannelCategory() throws GroupsException {
    IEntityGroup categoryGroup = GroupService.newGroup(ChannelDefinition.class);
    categoryGroup.setName(""); // name cannot be null
    categoryGroup.setCreatorID(""); // creatorId cannot be null
    categoryGroup.update();
    String id = categoryGroup.getKey();
    return new ChannelCategory(id);
  }

  /**
   * Creates a new channel category with the specified values.
   * @param name the name of the category
   * @param description the name of the description
   * @param creatorId the id of the creator or system
   * @return channelCategory the new channel category
   * @throws GroupsException
   */
  public ChannelCategory newChannelCategory( String name,
                                             String description,
                                             String creatorId )
      throws GroupsException
    {
        IEntityGroup categoryGroup = GroupService.newGroup(ChannelDefinition.class);
        categoryGroup.setName( name ); // name cannot be null
        categoryGroup.setCreatorID( creatorId ); // creatorId cannot be null
        categoryGroup.setDescription( description );
        categoryGroup.update();
        String id = categoryGroup.getKey();
        ChannelCategory cat = new ChannelCategory(id);
        cat.setName( name );
        cat.setDescription( description );
        cat.setCreatorId( creatorId );
        return cat;
  }

  /**
   * Gets an existing channel category.
   * @param channelCategoryId the id of the category to get
   * @return channelCategory the channel category
   * @throws org.jasig.portal.groups.GroupsException
   */
  public ChannelCategory getChannelCategory(String channelCategoryId) throws GroupsException {
    IEntityGroup categoryGroup = GroupService.findGroup(channelCategoryId);
    ChannelCategory category = new ChannelCategory(channelCategoryId);
    category.setName(categoryGroup.getName());
    category.setDescription(categoryGroup.getDescription());
    category.setCreatorId(categoryGroup.getCreatorID());
    return category;
  }

  /**
   * Gets top level channel category
   * @return channelCategories the new channel category
   * @throws org.jasig.portal.groups.GroupsException
   */
  public ChannelCategory getTopLevelChannelCategory() throws GroupsException {
    IEntityGroup categoryGroup = GroupService.getDistinguishedGroup(GroupService.CHANNEL_CATEGORIES);
    return getChannelCategory(categoryGroup.getKey());
  }

  /**
   * Gets all child channel categories for a parent category.
   * @return channelCategories the children categories
   * @throws org.jasig.portal.groups.GroupsException
   */
  public ChannelCategory[] getChildCategories(ChannelCategory parent) throws GroupsException {
    String parentKey = String.valueOf(parent.getId());
    IEntityGroup parentGroup = GroupService.findGroup(parentKey);
    List categories = new ArrayList();
    Iterator iter = parentGroup.getMembers();
    while (iter.hasNext()) {
      IGroupMember gm = (IGroupMember)iter.next();
      if (gm.isGroup()) {
        String categoryId = gm.getKey();
        categories.add(getChannelCategory(categoryId));
      }
    }
    return (ChannelCategory[])categories.toArray(new ChannelCategory[0]);
  }

  /**
   * Gets all child channel definitions for a parent category.
   * @return channelDefinitions the children channel definitions
   * @throws java.sql.SQLException
   * @throws org.jasig.portal.groups.GroupsException
   */
  public ChannelDefinition[] getChildChannels(ChannelCategory parent) throws SQLException, GroupsException {
    String parentKey = String.valueOf(parent.getId());
    IEntityGroup parentGroup = GroupService.findGroup(parentKey);
    List channelDefs = new ArrayList();
    Iterator iter = parentGroup.getMembers();
    while (iter.hasNext()) {
      IGroupMember gm = (IGroupMember)iter.next();
      if (gm.isEntity()) {
        int channelPublishId = Integer.parseInt(gm.getKey());
        channelDefs.add(getChannelDefinition(channelPublishId));
      }
    }
    return (ChannelDefinition[])channelDefs.toArray(new ChannelDefinition[0]);
  }

  /**
   * Gets the immediate parent categories of this category.
   * @return parents, the parent categories.
   * @throws org.jasig.portal.groups.GroupsException
   */
  public ChannelCategory[] getParentCategories(ChannelCategory child) throws GroupsException {
    String childKey = String.valueOf(child.getId());
    IEntityGroup childGroup = GroupService.findGroup(childKey);
    List parents = new ArrayList();
    Iterator iter = childGroup.getContainingGroups();
    while (iter.hasNext()) {
      IGroupMember gm = (IGroupMember)iter.next();
      if (gm.isGroup()) {
        String categoryId = gm.getKey();
        parents.add(getChannelCategory(categoryId));
      }
    }
    return (ChannelCategory[])parents.toArray(new ChannelCategory[0]);
  }

  /**
   * Gets the immediate parent categories of this channel definition.
   * @return parents, the parent categories.
   * @throws org.jasig.portal.groups.GroupsException
   */
  public ChannelCategory[] getParentCategories(ChannelDefinition child) throws GroupsException {
    String childKey = String.valueOf(child.getId());
    IEntity childEntity = GroupService.getEntity(childKey, ChannelDefinition.class);
    List parents = new ArrayList();
    Iterator iter = childEntity.getContainingGroups();
    while (iter.hasNext()) {
      IGroupMember gm = (IGroupMember)iter.next();
      if (gm.isGroup()) {
        String categoryId = gm.getKey();
        parents.add(getChannelCategory(categoryId));
      }
    }
    return (ChannelCategory[])parents.toArray(new ChannelCategory[0]);
  }

  /**
   * Persists a channel category.
   * @param category the channel category to persist
   * @throws org.jasig.portal.groups.GroupsException
   */
  public void saveChannelCategory(ChannelCategory category) throws GroupsException {
    IEntityGroup categoryGroup = GroupService.findGroup(category.getId());
    categoryGroup.setName(category.getName());
    categoryGroup.setDescription(category.getDescription());
    categoryGroup.setCreatorID(category.getCreatorId());
    categoryGroup.update();
  }

  /**
   * Deletes a channel category.
   * @param category the channel category to delete
   * @throws org.jasig.portal.groups.GroupsException
   */
  public void deleteChannelCategory(ChannelCategory category) throws GroupsException {
    String key = String.valueOf(category.getId());
    ILockableEntityGroup categoryGroup = GroupService.findLockableGroup(key,"UP_FRAMEWORK");
    categoryGroup.delete();
  }

  /**
   * Makes one category a child of another.
   * @param child the source category
   * @param parent the destination category
   * @throws org.jasig.portal.groups.GroupsException
   */
  public void addCategoryToCategory(ChannelCategory child, ChannelCategory parent) throws GroupsException {
    String childKey = String.valueOf(child.getId());
    IEntityGroup childGroup = GroupService.findGroup(childKey);
    String parentKey = String.valueOf(parent.getId());
    IEntityGroup parentGroup = GroupService.findGroup(parentKey);
    parentGroup.addMember(childGroup);
    parentGroup.updateMembers();
  }

  /**
   * Makes one category a child of another.
   * @param child the category to remove
   * @param parent the category to remove from
   * @throws org.jasig.portal.groups.GroupsException
   */
  public void removeCategoryFromCategory(ChannelCategory child, ChannelCategory parent) throws GroupsException {
    String childKey = String.valueOf(child.getId());
    IEntityGroup childGroup = GroupService.findGroup(childKey);
    String parentKey = String.valueOf(parent.getId());
    IEntityGroup parentGroup = GroupService.findGroup(parentKey);
    parentGroup.removeMember(childGroup);
    parentGroup.updateMembers();
  }

  /**
   * Associates a channel definition with a category.
   * @param channelDef the channel definition
   * @param category the channel category to which to associate the channel definition
   * @throws org.jasig.portal.PortalException
   */
  public void addChannelToCategory(ChannelDefinition channelDef, ChannelCategory category) throws PortalException {
    String channelDefKey = String.valueOf(channelDef.getId());
    IEntity channelDefEntity = GroupService.getEntity(channelDefKey, ChannelDefinition.class);
    IEntityGroup categoryGroup = GroupService.findGroup(category.getId());
    categoryGroup.addMember(channelDefEntity);
    categoryGroup.updateMembers();
  }

  /**
   * Disassociates a channel definition from a category.
   * @param channelDef the channel definition
   * @param category the channel category from which to disassociate the channel definition
   * @throws org.jasig.portal.PortalException
   */
  public void removeChannelFromCategory(ChannelDefinition channelDef, ChannelCategory category) throws PortalException {
    String channelDefKey = String.valueOf(channelDef.getId());
    IEntity channelDefEntity = GroupService.getEntity(channelDefKey, ChannelDefinition.class);
    String categoryKey = String.valueOf(category.getId());
    IEntityGroup categoryGroup = GroupService.findGroup(categoryKey);
    categoryGroup.removeMember(channelDefEntity);
    categoryGroup.updateMembers();
  }


  protected static final PreparedStatement getChannelPstmt(Connection con) throws SQLException {
    String sql = "SELECT UC.CHAN_TITLE, UC.CHAN_DESC, UC.CHAN_CLASS, UC.CHAN_TYPE_ID, " +
                 "UC.CHAN_PUBL_ID, UC.CHAN_APVL_ID, UC.CHAN_PUBL_DT, UC.CHAN_APVL_DT, " +
                 "UC.CHAN_TIMEOUT, UC.CHAN_EDITABLE, UC.CHAN_HAS_HELP, UC.CHAN_HAS_ABOUT, " +
                 "UC.CHAN_NAME, UC.CHAN_FNAME, UC.CHAN_SECURE";

    if (RDBMServices.getDbMetaData().supportsOuterJoins()) {
      sql += ", CHAN_PARM_NM, CHAN_PARM_VAL, CHAN_PARM_OVRD, CHAN_PARM_DESC FROM " + RDBMServices.getDbMetaData().getJoinQuery().getQuery("channel");
    } else {
      sql += " FROM UP_CHANNEL UC WHERE";
    }

    sql += " UC.CHAN_ID=?";

    return con.prepareStatement(sql);
  }

  protected static final PreparedStatement getChannelParamPstmt(Connection con) throws SQLException {
    if (RDBMServices.getDbMetaData().supportsOuterJoins()) {
      return null;
    } else {
      return con.prepareStatement("SELECT CHAN_PARM_NM, CHAN_PARM_VAL,CHAN_PARM_OVRD,CHAN_PARM_DESC FROM UP_CHANNEL_PARAM WHERE CHAN_ID=?");
    }
  }

  protected static final PreparedStatement getChannelMdataPstmt(Connection con) throws SQLException {
      return con.prepareStatement("SELECT LOCALE, CHAN_TITLE, CHAN_DESC, CHAN_NAME FROM UP_CHANNEL_MDATA WHERE CHAN_ID=?");
  }

}
TOP

Related Classes of org.jasig.portal.RDBMChannelRegistryStore

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.