/* 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.context.CatalogIndexAdapter; import com.esri.gpt.catalog.context.CatalogIndexException; import com.esri.gpt.catalog.lucene.RemoteIndexer; import com.esri.gpt.framework.collection.StringAttributeMap; import com.esri.gpt.framework.collection.StringSet; import com.esri.gpt.framework.context.RequestContext; import com.esri.gpt.framework.security.principal.Publisher; import com.esri.gpt.framework.sql.BaseDao; import com.esri.gpt.framework.util.Val; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; /** * Database access object associated with item collections. */ public class CollectionDao extends BaseDao { /** class variables ========================================================= */ /** Logger */ private static Logger LOGGER = Logger.getLogger(CollectionDao.class.getName()); /** constructors =========================================================== */ /** * Constructs with an associated request context. * @param requestContext the request context */ public CollectionDao(RequestContext requestContext) { super(requestContext); } /** properties ============================================================= */ /** * Gets the catalog index adapter. * @return the the catalog index adapter (null if none) */ private CatalogIndexAdapter getCatalogIndexAdapter() { return getRequestContext().getCatalogConfiguration().makeCatalogIndexAdapter(getRequestContext()); } /** * Gets the collection table name. * @return the collection table name */ public String getCollectionTableName() { return this.getTablePrefix()+"COLLECTION"; } /** * Gets the collection member table name. * @return the collection member table name */ public String getCollectionMemberTableName() { return this.getTablePrefix()+"COLLECTION_MEMBER"; //return "TMP_COLLECTION_MEMBER"; } /** * Gets resource table name. * @return resource table name */ private String getResourceTableName() { return this.getRequestContext().getCatalogConfiguration().getResourceTableName(); } /** * Gets the table prefix. * @return the table prefix */ public String getTablePrefix() { return this.getRequestContext().getCatalogConfiguration().getTablePrefix(); } /** * Determine if collections are in use. * @return <code>true</code> if collections are in use */ public boolean getUseCollections() { RequestContext context = this.getRequestContext(); StringAttributeMap params = context.getCatalogConfiguration().getParameters(); String s = Val.chkStr(params.getValue("catalog.useCollections")); return s.equalsIgnoreCase("true"); } /** methods ================================================================= */ /** * Adds a set of document UUIDS to a collection. * @param docUuids the set of document UUIDS * @param colUuid the collection UUID * @return the number of records inserted * @throws SQLException if an exception occurs while communicating with the database * @throws CatalogIndexException is an exception occurs while writing to the index */ public int addMembers(Publisher publisher, StringSet docUuids, String colUuid) throws SQLException, CatalogIndexException { PreparedStatement st1 = null; PreparedStatement st2 = null; PreparedStatement stR = null; int nBatch = 0; StringSet indexableUuids = new StringSet(); try { String table = this.getCollectionMemberTableName(); String tableR = this.getResourceTableName(); String sql1 = "SELECT DOCUUID FROM "+table+" WHERE DOCUUID=? AND COLUUID=?"; String sql2 = "INSERT INTO "+table+" (DOCUUID,COLUUID) VALUES (?,?)"; String sqlR = "SELECT APPROVALSTATUS FROM "+tableR+" WHERE DOCUUID=?"; Connection con = this.returnConnection().getJdbcConnection(); st1 = con.prepareStatement(sql1); st2 = con.prepareStatement(sql2); stR = con.prepareStatement(sqlR); for (String docUuid: docUuids) { boolean bInsert = true; st1.clearParameters(); st1.setString(1,docUuid); st1.setString(2,colUuid); ResultSet rs1 = st1.executeQuery(); if (rs1.next()) bInsert = false; rs1.close(); if (bInsert) { stR.clearParameters(); stR.setString(1,docUuid); ResultSet rsR = stR.executeQuery(); if (rsR.next()) { String status = Val.chkStr(rsR.getString(1)); if (MmdEnums.ApprovalStatus.isPubliclyVisible(status)) { indexableUuids.add(docUuid); } } rsR.close(); st2.setString(1,docUuid); st2.setString(2,colUuid); st2.addBatch(); nBatch++; } } st1.close(); st1 = null; if (nBatch > 0) { st2.executeBatch(); } } finally { CollectionDao.closeStatement(st1); CollectionDao.closeStatement(st2); CollectionDao.closeStatement(stR); } if (indexableUuids.size() > 0) { this.reindex(publisher,indexableUuids); } return nBatch; } /** * Queries named collections. * @return the list {colUuid,shortName} * @throws SQLException if an exception occurs while communicating with the database */ public List<String[]> queryCollections() throws SQLException { PreparedStatement st = null; ArrayList<String[]> al = new ArrayList<String[]>(); try { String table = this.getCollectionTableName(); String sql = null; if (getIsDbCaseSensitive(this.getRequestContext())) { sql = "SELECT COLUUID,SHORTNAME FROM "+table+ " ORDER BY UPPER(SHORTNAME) ASC"; } else { sql = "SELECT COLUUID,SHORTNAME FROM "+table+ " ORDER BY UPPER(SHORTNAME) ASC"; } this.logExpression(sql); Connection con = this.returnConnection().getJdbcConnection(); st = con.prepareStatement(sql); ResultSet rs = st.executeQuery(); while (rs.next()) { if (Thread.currentThread().isInterrupted()) return null; String uuid = Val.chkStr(rs.getString(1)); String name = Val.chkStr(rs.getString(2)); al.add(new String[]{uuid,name}); } } finally { CollectionDao.closeStatement(st); } return al; } /** * Re-indexes a set of documents. * @param publisher the publisher * @param uuids the set of document UUIDS * @throws SQLException if an exception occurs while communicating with the database * @throws CatalogIndexException is an exception occurs while writing to the index */ private void reindex (Publisher publisher, StringSet uuids) throws SQLException, CatalogIndexException { if (uuids.size() == 0) return; StringAttributeMap params = this.getRequestContext().getCatalogConfiguration().getParameters(); String param = Val.chkStr(params.getValue("lucene.useRemoteWriter")); boolean bUseRemoteWriter = param.equalsIgnoreCase("true"); param = Val.chkStr(params.getValue("lucene.useLocalWriter")); boolean bUseLocalWriter = !param.equalsIgnoreCase("false"); if (bUseRemoteWriter) { RemoteIndexer remoteIndexer = new RemoteIndexer(); remoteIndexer.send(this.getRequestContext(),"publish", uuids.toArray(new String[0])); } if (bUseLocalWriter) { CatalogIndexAdapter indexAdapter = getCatalogIndexAdapter(); for (String uuid: uuids) { indexAdapter.publishDocument(uuid,publisher); } } } /** * Removes a set of document UUIDS from a collection. * @param docUuids the set of document UUIDS * @param colUuid the collection UUID * @return the number of records removed * @throws SQLException if an exception occurs while communicating with the database * @throws CatalogIndexException is an exception occurs while writing to the index */ public int removeMembers(Publisher publisher, StringSet docUuids, String colUuid) throws SQLException, CatalogIndexException { PreparedStatement st1 = null; PreparedStatement st2 = null; PreparedStatement stR = null; int nBatch = 0; StringSet indexableUuids = new StringSet(); try { String table = this.getCollectionMemberTableName(); String tableR = this.getResourceTableName(); String sql1 = "SELECT DOCUUID FROM "+table+" WHERE DOCUUID=? AND COLUUID=?"; String sql2 = "DELETE FROM "+table+" WHERE DOCUUID=? AND COLUUID=?"; String sqlR = "SELECT APPROVALSTATUS FROM "+tableR+" WHERE DOCUUID=?"; Connection con = this.returnConnection().getJdbcConnection(); st1 = con.prepareStatement(sql1); st2 = con.prepareStatement(sql2); stR = con.prepareStatement(sqlR); for (String docUuid: docUuids) { boolean bRemove = false; st1.clearParameters(); st1.setString(1,docUuid); st1.setString(2,colUuid); ResultSet rs1 = st1.executeQuery(); if (rs1.next()) bRemove = true; rs1.close(); if (bRemove) { stR.clearParameters(); stR.setString(1,docUuid); ResultSet rsR = stR.executeQuery(); if (rsR.next()) { String status = Val.chkStr(rsR.getString(1)); if (MmdEnums.ApprovalStatus.isPubliclyVisible(status)) { indexableUuids.add(docUuid); } } rsR.close(); st2.setString(1,docUuid); st2.setString(2,colUuid); st2.addBatch(); nBatch++; } } st1.close(); st1 = null; if (nBatch > 0) { st2.executeBatch(); } } finally { CollectionDao.closeStatement(st1); CollectionDao.closeStatement(st2); CollectionDao.closeStatement(stR); } if (indexableUuids.size() > 0) { this.reindex(publisher,indexableUuids); } return nBatch; } }