/*BEGINPROLOGUE**************************************************************** * @copyright(disclaimer) * * * * DISCLAIMER OF WARRANTIES. * * * * The following IBM Content Manager Enterprise Edition code is sample code * * created by IBM Corporation. IBM grants you a nonexclusive copyright * * license to use this sample code example to generate similar function * * tailored to your own specific needs. This sample code is not part of any * * standard IBM product and is provided to you solely for the purpose of * * assisting you in the development of your applications. This example has * * not been thoroughly tested under all conditions. IBM, therefore cannot * * guarantee nor may you imply reliability, serviceability, or function of * * these programs. The code is provided "AS IS", without warranty of any * * kind. IBM shall not be liable for any damages arising out of your or any * * other parties use of the sample code, even if IBM has been advised of the * * possibility of such damages. If you do not agree with these terms, do not * * use the sample code. * * * * Licensed Materials - Property of IBM * * 5724-B19, 5697-H60 * * © Copyright IBM Corp. 1994, 2013 All Rights Reserved. * * * * US Government Users Restricted Rights - Use, duplication or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * * * * @endCopyright * *****************************************************************************/ // Imports import com.ibm.mm.sdk.common.*; import com.ibm.mm.sdk.server.*; import java.io.*; import java.util.ArrayList; /************************************************************************************************ * FILENAME: SHoldItemICM.java * -------------------------------------------------------------------------------- * DESCRIPTION: An item type which is enabled the hold container option is the hold container * item type. Items created under hold container item type are hold containers. * * An item type which is enabled the on-hold option is the on-hold item type. Items * created under on-hold item type can be put into hold containers. An item is * called on-hold item when it is put into hold container. * * Both hold container option and on-hold option can not be enabled on document * part item type classification. * * User should have the ItemRetentionAdmin, ItemSetHoldAdmin or SetItemHoldDelete * privilege on both hold container and on-hold item to perform addHold and removeHold * operations. * * On-hold items are not able to be deleted and reindexed(moved). But on-hold items can be * updated if the multiple version is enabled on the item type in which the on-hold * items are created. Update may fail if it causes the deletion on old on-hold version. * * User can query all on-hold items in a hold container and query all hold containers * one on-hold item may exist in. * * User can use on-hold indicator method to get the on-hold status for a given item. * --------------------------------------------------------------------------------- * DEMONSTRATION: Enable hold container option on item type. * Enable on-hold option on item type. * Creating hold containers. * Creating on-hold items. * Adding items to hold containers. * Removing items from hold containers. * Using on-hold indicator method to show on-hold status for items. * Querying on-hold items by specifying a hold container. * Querying hold containers by specifying a on-hold item. * --------------------------------------------------------------------------- * COMMANDLINE USAGE: java SHoldItemICM <database> <userName> <password> * --------------------------------------------------------------------------- * PREREQUISITES: The Data Model must be defined. If needed please run the following Samples * - SItemTypeCreationICM * --------------------------------------------------------------------------- * FILES REQUIRED: SConnectDisconnectICM.java * SItemTypeCreationICM.java * SLinksICM.java * SItemRetrievalICM.java ************************************************************************************************/ public class SHoldItemsICM{ //------------------------------------------------------------- // Main //------------------------------------------------------------- /** * Run the Sample. * @param argv[] String Array containing arguments. Optional arguments are <databse> <userName> <password>. */ public static void main(String argv[]) throws DKException, Exception{ // Defaults for connecting to the database. String database = SConnectDisconnectICM.DEFAULT_DATABASE; String userName = SConnectDisconnectICM.DEFAULT_USERNAME; String password = SConnectDisconnectICM.DEFAULT_PASSWORD; //------------------------------------------------------------ // Checking for input parameters //-------------------------------------------------------------- if (argv.length < 3) { // if not all 3 arguments were specified, use defaults and report correct usage. System.out.println("Usage: " ); System.out.println(" java SHoldItemsICM <database> <userName> <password> " ); System.out.println(" *** Some parameters not specified, using defaults..." ); System.out.println(""); } else { // otherwise enough parameters were specified, use the first 3 for the 3 parameters. if (argv.length > 0) database = argv[0]; if (argv.length > 1) userName = argv[1]; if (argv.length > 2) password = argv[2]; }//end else String ver = SConnectDisconnectICM.VERSION; System.out.println("==========================================="); System.out.println("IBM DB2 Content Manager v"+ver); System.out.println("Sample Program: SHoldItemsICM"); System.out.println("-------------------------------------------"); System.out.println(" Database: "+database); System.out.println(" UserName: "+userName); System.out.println("==========================================="); try{ //------------------------------------------------------------- // Connect to datastore //------------------------------------------------------------- // See Sample SConnectDisconnectICM for more information System.out.println("Connecting to datastore (Database '"+database+"', UserName '"+userName+"')..."); DKDatastoreICM dsICM = new DKDatastoreICM(); // Create new datastore object. dsICM.connect(database,userName,password,""); // Connect to the datastore. System.out.println("Connected to datastore (Database '"+dsICM.datastoreName()+"', UserName '"+dsICM.userName()+"')."); //------------------------------------------------------------- // Create Hold Container Items Type //------------------------------------------------------------- System.out.println("Defining Hold Container Item Type 'S_HoldContainer'..."); DKItemTypeDefICM holdItemType = new DKItemTypeDefICM(dsICM); // create a new Item Type Definition for hold container. holdItemType.setName("S_HoldContainer"); holdItemType.setDescription("My Simple Hold Container Item Type"); System.out.println("Retrieving attribute and adding it to Hold Container Item Type..."); DKDatastoreDefICM dsDefICM = (DKDatastoreDefICM) dsICM.datastoreDef(); DKAttrDefICM attr = (DKAttrDefICM) dsDefICM.retrieveAttr("S_varchar"); holdItemType.addAttr(attr); System.out.println("Set item type hold container option..."); holdItemType.setHoldContainer(true); // set hold container option for this item type before item type definition is persisted to datastore. holdItemType.add(); //Save the Item Type Definition. //--------------------------------------------------------------------------- //Enable on-hold options for item types // //Before putting items into hold container, enable on-hold option on item type //Except document part item type classification, we can enable on-hold option //on other item type classifications, including item, resource and document. // //--------------------------------------------------------------------------- System.out.println("Retrieve item types and set their on-hold options..."); DKItemTypeDefICM onHoldItemItemType = (DKItemTypeDefICM) dsDefICM.retrieveEntity("S_simple"); //item onHoldItemItemType.setItemsCanBeOnHold(true); onHoldItemItemType.update(); DKItemTypeDefICM onHoldResItemType = (DKItemTypeDefICM) dsDefICM.retrieveEntity("S_text"); //resource onHoldResItemType.setItemsCanBeOnHold(true); onHoldResItemType.update(); DKItemTypeDefICM onHoldDocItemType = (DKItemTypeDefICM) dsDefICM.retrieveEntity("S_docModel"); //document onHoldDocItemType.setItemsCanBeOnHold(true); onHoldDocItemType.update(); System.out.println("Creating Items"); DKDDO ddoItem = dsICM.createDDO("S_simple", DKConstant.DK_CM_ITEM); DKDDO ddoResource = dsICM.createDDO("S_text", DKConstant.DK_CM_RESOURCE); DKDDO ddoDoc = dsICM.createDDO("S_withChild", DKConstant.DK_CM_DOCUMENT); DKDDO ddoFolder = dsICM.createDDO("S_simple", DKConstant.DK_CM_ITEM); ddoItem.add(); ddoResource.add(); ddoDoc.add(); ddoFolder.add(); System.out.println("Created Items."); //------------------------------------------------------------ // Put items into hold container //------------------------------------------------------------ DKDDO holdContainer1 = dsICM.createDDO("S_HoldContainer", DKConstant.DK_CM_ITEM); DKDDO holdContainer2 = dsICM.createDDO("S_HoldContainer", DKConstant.DK_CM_RESOURCE); holdContainer1.add(); holdContainer2.add(); ArrayList<DKPidICM> itemsToBeOnHold = new ArrayList<DKPidICM>(); itemsToBeOnHold.add((DKPidICM)ddoItem.getPidObject()); itemsToBeOnHold.add((DKPidICM)ddoResource.getPidObject()); itemsToBeOnHold.add((DKPidICM)ddoDoc.getPidObject()); itemsToBeOnHold.add((DKPidICM)ddoFolder.getPidObject()); DKDatastoreExtICM dsExtICM = (DKDatastoreExtICM)dsICM.getExtension(DKConstant.DK_CM_DATASTORE_EXT); DKSequentialCollection errors = dsExtICM.addHolds((DKPidICM)holdContainer1.getPidObject(), itemsToBeOnHold); SHoldItemsICM.printHoldErrors(errors); ArrayList<DKPidICM> itemsToBeOnHold2 = new ArrayList<DKPidICM>(); itemsToBeOnHold2.add((DKPidICM)ddoItem.getPidObject()); itemsToBeOnHold2.add((DKPidICM)ddoResource.getPidObject()); errors = dsExtICM.addHolds((DKPidICM)holdContainer2.getPidObject(), itemsToBeOnHold2); SHoldItemsICM.printHoldErrors(errors); //------------------------------------------------------------------ //Check item on-hold status // //Before we use on-hold indicator method to check the on-hold status for an object, which //has already existed before we invoke addHolds or removeHolds method, //we should make sure to invoke DKDDO.retrieve() method to refresh the attributes. // //------------------------------------------------------------------ ddoItem.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoResource.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoDoc.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoFolder.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); System.out.println("On-hold flag in item ddoItem is: " + dsExtICM.isItemOnHold(ddoItem)); System.out.println("On-hold flag in item ddoResource is: " + dsExtICM.isItemOnHold(ddoResource)); System.out.println("On-hold flag in item ddoDoc is: " + dsExtICM.isItemOnHold(ddoDoc)); System.out.println("On-hold flag in item ddoResource is: " + dsExtICM.isItemOnHold(ddoFolder)); //------------------------------------------------------------------ //Get on-hold items in a hold container //------------------------------------------------------------------ DKRetrieveOptionsICM dkRetrieveOptions = DKRetrieveOptionsICM.createInstance(dsICM); dkRetrieveOptions.baseAttributes(true); dkRetrieveOptions.linksInbound(true); dkRetrieveOptions.linksOutbound(true); dsICM.retrieveObject(holdContainer1,dkRetrieveOptions.dkNVPair()); ArrayList<DKLink> outboundLinks1 = SLinksICM.getOutboundLinks(holdContainer1); System.out.println("Get the DDO(s) in the hold container1:"); for(DKLink link : outboundLinks1) { if(!link.getTypeName().equalsIgnoreCase(DKConstantICM.DK_ICM_LINKTYPENAME_DKHOLD)) continue; DKDDO ddo = (DKDDO)link.getTarget(); SItemRetrievalICM.printDDO(ddo); } dsICM.retrieveObject(holdContainer2,dkRetrieveOptions.dkNVPair()); ArrayList<DKLink> outboundLinks2 = SLinksICM.getOutboundLinks(holdContainer2); System.out.println("Get the DDO(s) in the hold container2:"); for(DKLink link : outboundLinks2) { if(!link.getTypeName().equalsIgnoreCase(DKConstantICM.DK_ICM_LINKTYPENAME_DKHOLD)) continue; DKDDO ddo = (DKDDO)link.getTarget(); SItemRetrievalICM.printDDO(ddo); } //------------------------------------------------------------------ //Get hold containers in which the given item exists //------------------------------------------------------------------ dsICM.retrieveObject(ddoItem,dkRetrieveOptions.dkNVPair()); ArrayList<DKLink> inboundLinks1 = SLinksICM.getInboundLinks(ddoItem); System.out.println("The ddoItem exists in the following hold containers:"); for(DKLink link : inboundLinks1) { if(!link.getTypeName().equalsIgnoreCase(DKConstantICM.DK_ICM_LINKTYPENAME_DKHOLD)) continue; DKDDO ddo = (DKDDO)link.getSource(); SItemRetrievalICM.printDDO(ddo); } dsICM.retrieveObject(ddoResource,dkRetrieveOptions.dkNVPair()); ArrayList<DKLink> inboundLinks2 = SLinksICM.getInboundLinks(ddoResource); System.out.println("The ddoResource exists in the following hold containers:"); for(DKLink link : inboundLinks2) { if(!link.getTypeName().equalsIgnoreCase(DKConstantICM.DK_ICM_LINKTYPENAME_DKHOLD)) continue; DKDDO ddo = (DKDDO)link.getSource(); SItemRetrievalICM.printDDO(ddo); } /************************************************************************************************************* * How to construct hold related queries in Content Manager version 85: * --------------------------------------------------------------------- * Basically, hold related query runs the same way as LINK query, the way to construct a query is also similar. * 1, The only big difference is : user MUST specify LINKTYPE=DKHold in query string when dealing with hold. * For example: * Query on-hold items in a hold container * /hold/OUTBOUNDLINK[@LINKTYPE ="DKHold"]/@TARGETITEMREF => * [@Title LIKE \"Java%\"] * Query to Get all Holds for a held item: * /onhold/INBOUNDLINK[@LINKTYPE= "DKHold"]/@SOURCEITEMREF => * * * 2, When no LINKTYPE is specified in a query string, the query will behavior the same as before, * which means it will not involve table which has hold. This will benefit for existing queries. * For example: * /MyItemType/OUTBOUNDLINK/@TARGETITEMREF => * [@VERSIONID = 1] * * If user for any reason wants to query both Link and Hold related tables/items without specify LINKTYPE, * a new query option was added for this. User can set query option DK_CM_PARM_USE_LINK_HOLD_UNION to true * to force query to access Union table which contains both hold and normal LINKTYPEs. * * 3, If a query string specify more than one LINKTYPEs and one of them is DKHold, such as * @LINKTYPE IN ("DKHold", "DkFolder"), an union view table will be used. It may have performance impact. ******************************************************************************************************************/ //------------------------------------------------------------------- // Attempt to delete the on-hold item //------------------------------------------------------------------- try { ddoItem.del(); } catch(DKException e) { if(e.errorCode() == DKConstantICM.DK_ICM_RC_DEL_ITEM_IN_HOLD_CONTAINER) System.out.println("Fail to delete the on-hold item ."); else System.out.println("Fail to delete item, exception:" + e.getMessage()); } //------------------------------------------------------------------- //Remove item out from hold container //------------------------------------------------------------------- ArrayList<DKPidICM> itemsMovedHold1 = new ArrayList<DKPidICM>(); itemsMovedHold1.add((DKPidICM)ddoItem.getPidObject()); itemsMovedHold1.add((DKPidICM)ddoResource.getPidObject()); itemsMovedHold1.add((DKPidICM)ddoDoc.getPidObject()); itemsMovedHold1.add((DKPidICM)ddoFolder.getPidObject()); System.out.println("Start to move items out from hold container1..."); errors = dsExtICM.removeHolds((DKPidICM)holdContainer1.getPidObject(), itemsMovedHold1); SHoldItemsICM.printHoldErrors(errors); ddoItem.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoResource.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoDoc.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoFolder.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); System.out.println("Items moved from hold container1 is done..."); System.out.println("After items moved out from hold container1:"); System.out.println("On-hold flag in item ddoItem is: " + dsExtICM.isItemOnHold(ddoItem)); System.out.println("On-hold flag in item ddoResource is: " + dsExtICM.isItemOnHold(ddoResource)); System.out.println("On-hold flag in item ddoDoc is: " + dsExtICM.isItemOnHold(ddoDoc)); System.out.println("On-hold flag in item ddoResource is: " + dsExtICM.isItemOnHold(ddoFolder)); holdContainer1.del(); //------------------------------------------------------------------ // Delete hold container // // Hold container deletion will result in deletion on hold links // associated with this hold container. //------------------------------------------------------------------ holdContainer2.del(); ddoItem.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoResource.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoDoc.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); ddoFolder.retrieve(DKConstant.DK_CM_CONTENT_ATTRONLY); System.out.println("container2 deletion is done..."); System.out.println("After container2 is deleted:"); System.out.println("On-hold flag in item ddoItem is: " + dsExtICM.isItemOnHold(ddoItem)); System.out.println("On-hold flag in item ddoResource is: " + dsExtICM.isItemOnHold(ddoResource)); System.out.println("On-hold flag in item ddoDoc is: " + dsExtICM.isItemOnHold(ddoDoc)); System.out.println("On-hold flag in item ddoResource is: " + dsExtICM.isItemOnHold(ddoFolder)); System.out.println("Deleting Items."); ddoItem.del(); ddoResource.del(); ddoDoc.del(); ddoFolder.del(); System.out.println("Retrieve item types and set their on-hold options to false..."); onHoldItemItemType = (DKItemTypeDefICM) dsDefICM.retrieveEntity("S_simple"); //item onHoldItemItemType.setItemsCanBeOnHold(false); onHoldItemItemType.update(); onHoldResItemType = (DKItemTypeDefICM) dsDefICM.retrieveEntity("S_text"); //resource onHoldResItemType.setItemsCanBeOnHold(false); onHoldResItemType.update(); onHoldDocItemType = (DKItemTypeDefICM) dsDefICM.retrieveEntity("S_docModel"); //document onHoldDocItemType.setItemsCanBeOnHold(false); onHoldDocItemType.update(); System.out.println("Delete Hold Container Item Type 'S_HoldContainer'..."); holdItemType = (DKItemTypeDefICM) dsDefICM.retrieveEntity("S_HoldContainer"); // hold item type if (holdItemType != null){ dsDefICM.del(holdItemType); } //------------------------------------------------------------- // Disconnect from datastore & Destroy Reference //------------------------------------------------------------- // See Sample SConnectDisconnectICM for more information System.out.println("Disconnecting from datastore & destroying reference..."); dsICM.disconnect(); dsICM.destroy(); System.out.println("Disconnected from datastore & destroying reference."); //------------------------------------------------------------- // Sample program completed without exception //------------------------------------------------------------- System.out.println("\n=========================================="); System.out.println("Sample program completed."); System.out.println("==========================================\n"); } //------------------------------------------------------------ // Catch & Print Exceptions //------------------------------------------------------------ catch (DKException exc){ SConnectDisconnectICM.printException(exc); // Print the exception using the function listed below. throw(exc); } catch (Exception exc) { SConnectDisconnectICM.printException(exc); // Print the exception using the function listed below. throw(exc); } }// end main public static void printHoldErrors(DKSequentialCollection errors) { if(errors != null) { System.out.println(" Number of Hold errors found: " + errors.cardinality()); dkIterator it = errors.createIterator(); int i = 0; DKErrorInfoItemICM errorInfo = null; while(it.more()) { try { i++; errorInfo = (DKErrorInfoItemICM)it.next(); System.out.println(" Hold error["+i+"] " + errorInfo.toString()); } catch (DKException e) { SConnectDisconnectICM.printException(e); } } } } }//end class SHoldItemsICM.java