Package com.esri.gpt.catalog.management

Source Code of com.esri.gpt.catalog.management.MmdQueryRequest

/* See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Esri Inc. 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 com.esri.gpt.catalog.management;
import com.esri.gpt.catalog.arcims.ImsMetadataAdminDao;
import com.esri.gpt.catalog.context.CatalogConfiguration;
import com.esri.gpt.catalog.harvest.repository.HrRecord.HarvestFrequency;
import com.esri.gpt.catalog.harvest.repository.HrRecord.RecentJobStatus;
import com.esri.gpt.catalog.management.MmdEnums.PublicationMethod;
import com.esri.gpt.control.webharvest.protocol.ProtocolParseException;
import com.esri.gpt.framework.collection.StringAttributeMap;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.jsf.RoleMap;
import com.esri.gpt.framework.request.PageCursor;
import com.esri.gpt.framework.security.identity.IdentityException;
import com.esri.gpt.framework.security.metadata.MetadataAcl;
import com.esri.gpt.framework.security.principal.Groups;
import com.esri.gpt.framework.security.principal.Publisher;
import com.esri.gpt.framework.security.principal.User;
import com.esri.gpt.framework.security.principal.Users;
import com.esri.gpt.framework.sql.ManagedConnection;
import com.esri.gpt.framework.util.DateProxy;
import com.esri.gpt.framework.util.Val;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.NamingException;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

/**
* Queries metadata documents based upon associated query criteria.
*/
public class MmdQueryRequest extends MmdRequest {


// class variables =============================================================
private static final Logger LOGGER = Logger.getLogger(MmdQueryRequest.class.getCanonicalName());

// instance variables ==========================================================
private ImsMetadataAdminDao     adminDao;
private Groups                  allGroups = null;
private boolean                 enableEditForAllPubMethods = false;
private boolean                 isGptAdministrator;
private String                  tblImsUser;
private HashMap<String, String> hmEditablePublishers = new HashMap<String, String>();


// constructors ================================================================
/**
* Construct a metadata management query request.
* @param requestContext the request context
* @param publisher the publisher
* @param criteria the request criteria
* @param result the request result
*/
public MmdQueryRequest(RequestContext requestContext, Publisher publisher,
    MmdCriteria criteria, MmdResult result) {
  super(requestContext, publisher, criteria, result);
}

// properties ==================================================================

// methods =====================================================================
/**
* Executes the query request.
* @throws SQLException if a database exception occurs
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException
*/
public void execute() throws SQLException, IdentityException, NamingException,
    ParserConfigurationException, SAXException, IOException {

  // intitalize
  PreparedStatement st = null;
  PreparedStatement stCount = null;
  PreparedStatement stUser = null;
  PreparedStatement stCol = null;
  MmdQueryCriteria criteria = getQueryCriteria();
  MmdRecords records = getQueryResult().getRecords();
  PageCursor pageCursor = getQueryResult().getPageCursor();
  criteria.getDateRange().check();
  pageCursor.setTotalRecordCount(0);

  adminDao = new ImsMetadataAdminDao(getRequestContext());
  tblImsUser = getRequestContext().getCatalogConfiguration().getUserTableName();
  Users editablePublishers = Publisher.buildSelectablePublishers(getRequestContext(), false);
  for (User u : editablePublishers.values()) {
    if (u.getName().length() > 0) {
      hmEditablePublishers.put(u.getName().toLowerCase(), u.getKey());
    }
  }
  User tmpUser = new User();
  tmpUser.setDistinguishedName("*");
  getRequestContext().newIdentityAdapter().readUserGroups(tmpUser);
  allGroups = tmpUser.getGroups();

  isGptAdministrator = new RoleMap(getRequestContext().getUser()).get("gptAdministrator");
 
  try {

    // establish the connection
    ManagedConnection mc = returnConnection();
    Connection con = mc.getJdbcConnection();
   
    // determine if the database is case sensitive
    StringAttributeMap params = getRequestContext().getCatalogConfiguration().getParameters();
    String s = Val.chkStr(params.getValue("database.isCaseSensitive"));
    boolean isDbCaseSensitive = !s.equalsIgnoreCase("false");
   
    s = Val.chkStr(params.getValue("catalog.enableEditForAllPubMethods"));
    this.enableEditForAllPubMethods = s.equalsIgnoreCase("true");
   
    // determine if collections are being used
    List<String[]> collections = null;
    CollectionDao colDao = new CollectionDao(getRequestContext());
    boolean hasCollections = false;
    boolean useCollections = colDao.getUseCollections();
    String sColMemberTable = colDao.getCollectionMemberTableName();
    String sqlCol = "SELECT COLUUID FROM "+sColMemberTable+
                    " WHERE DOCUUID=?";
    if (useCollections) {
      collections = colDao.queryCollections();
      hasCollections = (collections.size() > 0);
    }
   
    // username query
    String sqlUser = "SELECT USERNAME FROM "+tblImsUser+" WHERE USERID=?";

    // start the SQL expression
    StringBuilder sbSql = new StringBuilder();
    StringBuilder sbCount = new StringBuilder();
    StringBuilder sbFrom = new StringBuilder();
    StringBuilder sbWhere = new StringBuilder();
    sbSql.append("SELECT A.TITLE,A.DOCUUID,A.SITEUUID,A.OWNER");
    sbSql.append(",A.APPROVALSTATUS,A.PUBMETHOD,A.UPDATEDATE,A.ACL");
    sbSql.append(",A.ID,A.HOST_URL,A.FREQUENCY,A.SEND_NOTIFICATION,A.PROTOCOL");
    sbSql.append(",A.FINDABLE,A.SEARCHABLE,A.SYNCHRONIZABLE");
    sbCount.append("SELECT COUNT(*)");

    // append from clause
    sbFrom.append(" FROM ").append(getResourceTableName()).append(" A");
    sbSql.append(sbFrom);
    sbCount.append(sbFrom);

    // build the where clause
    Map<String,Object> args = criteria.appendWherePhrase(
        getRequestContext(),"A",sbWhere,getPublisher());

    // collection filter
    String sColUuid = Val.chkStr(criteria.getCollectionUuid());
    if (useCollections && hasCollections && (sColUuid.length() > 0)) {
      String sub = "SELECT DOCUUID FROM "+sColMemberTable+
                   " WHERE COLUUID=?";
      if (sbWhere.length() > 0) sbWhere.append(" AND ");
      sbWhere.append("(A.DOCUUID IN ("+sub+"))");
    }
   
    // append the where clause expressions
    if (sbWhere.length() > 0) {
      sbSql.append(" WHERE ").append(sbWhere.toString());
      sbCount.append(" WHERE ").append(sbWhere.toString());
    }

    // append the order by clause
    String sSortColumn = criteria.getSortOption().getColumnKey();
    String sSortDir = criteria.getSortOption().getDirection().toString();
    if (sSortColumn.equalsIgnoreCase("title")) {
      if (isDbCaseSensitive) {
        sSortColumn = "UPPER(A.TITLE)";
      } else {
        sSortColumn = "A.TITLE";
      }
    } else if (sSortColumn.equalsIgnoreCase("uuid")) {
      sSortColumn = "A.DOCUUID";
    } else if (sSortColumn.equalsIgnoreCase("status")) {
      sSortColumn = "A.APPROVALSTATUS";
    } else if (sSortColumn.equalsIgnoreCase("method")) {
      sSortColumn = "A.PUBMETHOD";
    } else if (sSortColumn.equalsIgnoreCase("acl")) {
      sSortColumn = "A.ACL";
    } else if (sSortColumn.equalsIgnoreCase("updatedate")) {
      sSortColumn = "A.UPDATEDATE";
    } else {
      sSortColumn = "A.UPDATEDATE";
      sSortDir = "DESC";
      criteria.getSortOption().setColumnKey("updatedate");
      criteria.getSortOption().setDirection("desc");
    }
    sbSql.append(" ORDER BY ");
    sbSql.append(sSortColumn).append(" ").append(sSortDir.toUpperCase());
    if (!sSortColumn.equalsIgnoreCase("A.UPDATEDATE")) {
      sbSql.append(", A.UPDATEDATE DESC");
    }

    // prepare the statements
    st = con.prepareStatement(sbSql.toString());
    stCount = con.prepareStatement(sbCount.toString());
    stUser = con.prepareStatement(sqlUser);
    int n = 1;
    criteria.applyArgs(st, n, args);
    n = criteria.applyArgs(stCount, n, args);
    if (useCollections && hasCollections) {
      stCol = con.prepareStatement(sqlCol);
      if (sColUuid.length() > 0) {
        st.setString(n,sColUuid);
        stCount.setString(n,sColUuid);
        n++;
      }
    }

    // query the count
    //System.err.println(sbCount.toString());
    //System.err.println(sbSql.toString());
    logExpression(sbCount.toString());
    ResultSet rsCount = stCount.executeQuery();
    if (rsCount.next()) {
      pageCursor.setTotalRecordCount(rsCount.getInt(1));
    }
    stCount.close();
    stCount = null;

    // query records if a count was found
    pageCursor.checkCurrentPage();
    if (pageCursor.getTotalRecordCount() > 0) {

      // set the start record and the number of records to retrieve
      int nCurPage = pageCursor.getCurrentPage();
      int nRecsPerPage = getQueryResult().getPageCursor().getRecordsPerPage();
      int nStartRecord = ((nCurPage - 1) * nRecsPerPage) + 1;
      int nMaxRecsToRetrieve = nCurPage * nRecsPerPage;
      st.setMaxRows(nMaxRecsToRetrieve);

      // determine publisher names associated with editable records

      // execute the query
      logExpression(sbSql.toString());
      ResultSet rs = st.executeQuery();

      // build the record set
      int nCounter = 0;

      while (rs.next()) {
        n = 1;
        nCounter++;
        if (nCounter >= nStartRecord) {
          MmdRecord record = new MmdRecord();
          records.add(record);
         
          // find the username of the owner
          int nUserid = rs.getInt(4);
          String sUsername = "";
          stUser.clearParameters();
          stUser.setInt(1,nUserid);
          ResultSet rs2 = stUser.executeQuery();
          if (rs2.next()) sUsername = Val.chkStr(rs2.getString(1));
          if (sUsername.length() == 0) sUsername = ""+nUserid;
          rs2.close();
         
          // determine collection membership
          StringBuilder sbCol = new StringBuilder();
          if (useCollections && hasCollections) {
            String sDocUuid = rs.getString(2);
            stCol.clearParameters();
            stCol.setString(1,sDocUuid);
            ResultSet rs3 = stCol.executeQuery();
            while (rs3.next()) {
              String sCUuid = rs3.getString(1);
              for (String[] col: collections) {
                if (sCUuid.equals(col[0])) {
                  if (sbCol.length()> 0) sbCol.append(",");
                  sbCol.append(col[1]);
                  break;
                }
              }
            }
            rs3.close();
            if (sbCol.length() > 0) {
              record.setCollectionMembership(sbCol.toString());
            }
          }
         
          try {
            readRecord(rs,record,sUsername);
          } catch (Exception ex) {
            LOGGER.log(Level.WARNING, "Error reading record.", ex);
          }

          // break if we hit the max value for the cursor
          if (records.size() >= nRecsPerPage) {
            break;
          }

        }
      }

      TreeMap<String, MmdRecord> recordsMap = new TreeMap<String, MmdRecord>(String.CASE_INSENSITIVE_ORDER);
      StringBuilder keys = new StringBuilder();

      for (MmdRecord r : records) {
        if (r.getProtocol()==null) continue;
        recordsMap.put(r.getUuid(), r);
        if (keys.length()>0) {
          keys.append(",");
        }
        keys.append("'").append(r.getUuid().toUpperCase()).append("'");
      }

      readJobStatus(con, recordsMap, keys.toString());
      readLastHarvestDate(con, recordsMap, keys.toString());
    }

  } finally {
    closeStatement(st);
    closeStatement(stCount);
    closeStatement(stUser);
    closeStatement(stCol);
  }
}

/**
* Reads owner id.
* @param con database connection
* @return owner id or -1 if no owner id
* @throws SQLException if accessing database fails
*/
private int readImsOwnerId(Connection con) throws SQLException {
  int nUserId = -1;
  PreparedStatement st = null;
  try {
    boolean bQuery = true;
    CatalogConfiguration config = getRequestContext().getCatalogConfiguration();
    String sUserTable = config.getUserTableName();
    String sDN = getQueryCriteria().getOwner();

    // only an administrator can query all records
    if (sDN.length() == 0) {
      if (getPublisher().getIsAdministrator()) {
        bQuery = false;
      } else {
        sDN = getPublisher().getDistinguishedName();
        getQueryCriteria().setOwner(sDN);
      }
    }

    // execute the query
    if (bQuery) {
        StringBuilder sbSql = new StringBuilder();
        sbSql.append("SELECT USERID FROM ").append(sUserTable);
        sbSql.append(" WHERE UPPER(DN)=?");
        logExpression(sbSql.toString());
        st = con.prepareStatement(sbSql.toString());
        st.setString(1,sDN.toUpperCase());
        ResultSet rs = st.executeQuery();
        if (rs.next()) {
          nUserId = rs.getInt(1);
        }
    }
  } finally {
    closeStatement(st);
  }
  return nUserId;
}

/**
* Reads the ArcIMS owner id to be queried.
* @param con the JDBC connection
* @return the ArcIMS owner name to be queried (empty string for any owner)
* @throws SQLException if a database exception occurs
*/
private String readImsOwnerName(Connection con) throws SQLException {
  String sImsOwnerName = "-1";
  PreparedStatement st = null;
  try {
    boolean bQuery = true;
    CatalogConfiguration config = getRequestContext().getCatalogConfiguration();
    String sUserTable = config.getUserTableName();
    String sDN = getQueryCriteria().getOwner();

    // only an administrator can query all records
    if (sDN.length() == 0) {
      if (getPublisher().getIsAdministrator()) {
        bQuery = false;
        sImsOwnerName = "";
      } else {
        sDN = getPublisher().getDistinguishedName();
        getQueryCriteria().setOwner(sDN);
      }
    }

    // execute the query
    if (bQuery) {
      StringBuilder sbSql = new StringBuilder();
      sbSql.append("SELECT USERNAME FROM ").append(sUserTable);
      sbSql.append(" WHERE UPPER(DN)=?");
      logExpression(sbSql.toString());
      st = con.prepareStatement(sbSql.toString());
      st.setString(1,sDN.toUpperCase());
      ResultSet rs = st.executeQuery();
      if (rs.next()) {
        sImsOwnerName = rs.getString(1);
      }
    }
  } finally {
    closeStatement(st);
  }
  return sImsOwnerName;
}

/**
* Reads record data.
* @param rs result set to read from
* @param record record to write to
* @param ownername the username of the record owner
* @throws SQLException if accessing database fails
* @throws ParserConfigurationException if unable to reach parser configuration
* @throws IOException if unable to perform IO operation
* @throws SAXException if unable to parse XML data
* @throws ProtocolParseException if unable to parse protocol
*/
private void readRecord(ResultSet rs, MmdRecord record, String ownername) throws SQLException, ParserConfigurationException, IOException, SAXException, ProtocolParseException {
  int n = 1;

  // set the title and uuid
  record.setTitle(rs.getString(n++));
  record.setUuid(rs.getString(n++));
  record.setSiteUuid(rs.getString(n++));
  if (getActionCriteria().getSelectedRecordIdSet().contains(record.getUuid())) {
    record.setIsSelected(true);
  }

  // set the owner, approval status and publication method
  //record.setOwnerName(rs.getString(n++));
  n++; record.setOwnerName(ownername);
  record.setApprovalStatus(rs.getString(n++));
  record.setPublicationMethod(rs.getString(n++));

  // set the update date,
  Timestamp ts = rs.getTimestamp(n++);
  if (ts != null) {
    record.setSystemUpdateDate(ts);
    record.setFormattedUpdateDate(DateProxy.formatDate(ts));
  }

  // set the ACL
  String aclXml = rs.getString(n++);
  if (aclXml != null && aclXml.trim().length() > 0) {
    record.setMetadataAccessPolicyType("Restricted");
    MetadataAcl acl = new MetadataAcl(getRequestContext());
    record.setCurrentMetadataAccessPolicy(acl.makeGroupsfromXml(allGroups,aclXml));
    record.setCurrentMetadataAccessPolicyKeys(acl.makeGroupsKeysfromXml(allGroups,aclXml));
  } else {
    record.setMetadataAccessPolicyType("Unrestricted");
    record.setCurrentMetadataAccessPolicy("Unrestricted");
    record.setCurrentMetadataAccessPolicyKeys("Unrestricted");
  }

  // set harvesting specific data
  record.setLocalId(rs.getInt(n++));
  record.setHostUrl(rs.getString(n++));
  String frequency = Val.chkStr(rs.getString(n++));
  if (frequency.length()>0)
    record.setHarvestFrequency(HarvestFrequency.checkValueOf(frequency));
  record.setSendNotification(Val.chkBool(rs.getString(n++), false));
  String protocol = Val.chkStr(rs.getString(n++));
  if (protocol.length()>0)
    record.setProtocol(getApplicationConfiguration().getProtocolFactories().parseProtocol(protocol));

  // set the editable status
  boolean isEditor = record.getPublicationMethod().equalsIgnoreCase(PublicationMethod.editor.name());
  boolean isSEditor = record.getPublicationMethod().equalsIgnoreCase(PublicationMethod.seditor.name());

  boolean isProtocol = record.getProtocol()!=null;
  boolean isOwner = hmEditablePublishers.containsKey(record.getOwnerName().toLowerCase());
  record.setCanEdit(
    (this.enableEditForAllPubMethods || isEditor || isSEditor || isProtocol) &&
    (isOwner || (isProtocol && isGptAdministrator))
  );

  // TODO remove as this is a temporary fix
  boolean isOther = record.getPublicationMethod().equalsIgnoreCase(PublicationMethod.other.name());
  if (isOther && isProtocol) {
    record.setPublicationMethod(PublicationMethod.registration.name());
  }

  record.setFindable(Val.chkBool(rs.getString(n++), false));
  record.setSearchable(Val.chkBool(rs.getString(n++), false));
  record.setSynchronizable(Val.chkBool(rs.getString(n++), false));
}

/**
* Reads jobs statuses for each record in the collection
* @param con connection
* @param recordsMap records map
* @param keys keys
* @throws SQLException if accessing database fails
*/
private void readJobStatus(Connection con, TreeMap<String, MmdRecord> recordsMap, String keys) throws SQLException {
  if (keys.length()>0) {
    PreparedStatement st = null;
    ResultSet rs = null;
    try {
      st = con.prepareStatement("SELECT HARVEST_ID, JOB_STATUS FROM GPT_HARVESTING_JOBS_PENDING WHERE UPPER(HARVEST_ID) IN (" +keys.toString()+ ")");
      rs = st.executeQuery();

      while (rs.next()) {
        String harvestId = rs.getString(1);
        String jobStatus = rs.getString(2);
        MmdRecord r = recordsMap.get(harvestId);
        if (r!=null) {
          r.setRecentJobStatus(RecentJobStatus.checkValueOf(jobStatus));
        }
      }
    } finally {
      closeResultSet(rs);
      closeStatement(st);
    }
  }
}

/**
* Reads last harvest date for each record in the collection.
* @param con connection
* @param recordsMap records map
* @param keys keys
* @throws SQLException if accessing database fails
*/
private void readLastHarvestDate(Connection con, TreeMap<String, MmdRecord> recordsMap, String keys) throws SQLException {
  if (keys.length()>0) {
    PreparedStatement st = null;
    ResultSet rs = null;
    try {
      st = con.prepareStatement("SELECT HARVEST_ID, MAX(HARVEST_DATE) FROM GPT_HARVESTING_HISTORY WHERE UPPER(HARVEST_ID) IN (" +keys.toString()+ ") GROUP BY HARVEST_ID");
      rs = st.executeQuery();

      while (rs.next()) {
        String harvestId = rs.getString(1);
        Timestamp lastHarvestDate = rs.getTimestamp(2);
        MmdRecord r = recordsMap.get(harvestId);
        if (r!=null) {
          r.setLastHarvestDate(lastHarvestDate);
        }
      }
    } finally {
      closeResultSet(rs);
      closeStatement(st);
    }
  }
}
}
TOP

Related Classes of com.esri.gpt.catalog.management.MmdQueryRequest

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.