Monday, 4 June 2018

AT BCC customizations

1)How to add separate xxx repository tab in BCC  ?


We  can add the xxx repository as a separate tab in bcc as follows by doing the following changes.


The following steps we need to follow.

1)Modify the component
     \atg\remote\controlcenter\service\ApplicationConfigurationManager.properties  (OOTB)


     applicationFiles+=\
                       /abcd/xxx.xml



2)The file should be /abcd/xxx.xml and it will be as follows



<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE application-configuration
PUBLIC "-//Art Technology Group, Inc.//DTD BCC Application Configuration //EN"
"http://www.atg.com/dtds/application-configuration/application-configuration_1.0.dtd">
<applications>
     <application id="someNameId">
          <resource-bundle>com.webui.WebAppResources</resource-bundle>
          <display-name-resource>someNameId.displayName</display-name-resource>
          <destination-page>
               <url>/AssetManager/assetManager.jsp</url>
               <query-parameter key="project" value="-1" />
               <query-parameter key="activity" value="someNameId" />
          </destination-page>
          <acl>Profile$role$epubAdmin:read;Profile$role$epubSuperAdmin:read;Profile$role$epubManager:read;Profile$role$epubUser:read</acl>
          <initializer>
          </initializer>
          <sort-priority>30</sort-priority>
          <category>yourProjectExtras</category>
     </application>
</applications>

There should be  WebAppResources file in the path under the src folder.
            src/com/webui/WebAppResources
             It  contains the key values like someNameId.displayName = desired value.


3)The following file need to update.

  config/atg/web/assetmanager/configuration/taskConfiguration.xml (OOTB)

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE task-configuration
PUBLIC "-//Art Technology Group, Inc.//DTD Asset Manager Task Configuration//EN"
'http://www.atg.com/dtds/web/assetmanager/taskConfiguration_1.0.dtd'>
<task-configuration>

<activity id="">
</activity>

...

<!-- ===================================================================== -->
  <activity id="someNameId" inherit-from="assetManager.defaultEdit">
<activity-name>someNameId</activity-name>

  <operations>
      <operation>create</operation>
      <operation>delete</operation>
    </operations>

    <!-- Define tabs for the left pane -->
    <tabs>
      <tab-order>
        <tab-id>browse</tab-id>
        <tab-id>search</tab-id>
      </tab-order>
      <initial-tab>
        browse
      </initial-tab>

      <!-- Configure the Browse tab -->
      <tab id="browse">
        <display-name-resource>
          assetManager.tab.browse
        </display-name-resource>
        <page>
          /browse/browseTab.jsp
        </page>
        <views>
          <view-order>
            <view-id>someNameId.xx</view-id>
            <view-id>someOtherId.yy</view-id>
          </view-order>
          <initial-view>
            someNameId.xx
          </initial-view>

          <view id="someNameId.xx">
            <resource-bundle>com.webui.WebAppResources</resource-bundle>
            <display-name-resource>
              someNameId.xx.yy.zz
            </display-name-resource>
            <configuration>
              /com/xx/yy/repositories/zzzViewConfiguration
            </configuration>
            <page>
              /browse/list.jsp
            </page>
          </view>
       
          <view id="someOtherId.yy">
            <resource-bundle>com.webui.WebAppResources</resource-bundle>
            <display-name-resource>
              someNameId.xx.yy.zaa
            </display-name-resource>
            <configuration>
              /com/xx/yy/repositories/abcViewConfiguration
            </configuration>
            <page>
              /browse/list.jsp
            </page>
          </view>

        </views>
      </tab>
      <!-- Configure the Search tab -->
      <tab id="search">
        <display-name-resource>
          assetManager.tab.search
        </display-name-resource>
        <page>
          /search/searchTab.jsp
        </page>
        <views>
          <initial-view>
            form
          </initial-view>
          <view id="form">
            <page>
              /search/searchForm.jsp
            </page>
            <item-types>
              <item-type>/com/xx/yy/repositories/xxRepository:zz</item-type>
            </item-types>
          </view>
          <view id="results">
            <page>
              /search/searchResults.jsp
            </page>
            <operations>
              <!-- users/orgs/roles don't need link or unlink -->
              <operation combine="remove">link</operation>
              <operation combine="remove">unlink</operation>
            </operations>
          </view>
        </views>
      </tab>
    </tabs>
  </activity>

</task-configuration>



In the above configuration, operations creation,delete are optonal if it is only browse.

4)Need to implement the component as follows (which are mentioned above configuration).

-->/com/xx/yy/repositories/zzzViewConfiguration



# /com/xx/yy/repositories/zzzViewConfiguration
$class=atg.web.assetmanager.configuration.FilterableBrowseListViewConfiguration
$scope=session
# The path to the repository from which to draw the items
repositoryPath=/com/xx/yy/repositories/xxRepository
# The type of items to display
assetTypeName=xx

# Types the user is allowed to create in this view,this is requried if the above confiuration holds create,delete opeartion list
createableTypesList=itemType1,itemType2,itemType3

# Number of items to show per page
itemsPerPage=20

 
-->/com/xx/yy/repositories/xxRepository




# /com/xx/yy/repositories/zzzViewConfiguration
$class=atg.web.assetmanager.configuration.FilterableBrowseListViewConfiguration
$scope=session
# The path to the repository from which to draw the items
repositoryPath=/com/xx/yy/repositories/xxRepository
# The type of items to display
assetTypeName=yy

# Types the user is allowed to create in this view,this is requried if the above confiuration holds create,delete opeartion list
createableTypesList=itemType1,itemType2,itemType3

# Number of items to show per page
itemsPerPage=20


3)Files to Modify on adding one Repository Item (xxxRepItem in xxxRepository) in the existing repository definition file.And that item should be in the browse and fine/search mode in BCC.


1)Versioned/config/atg/remote/content/browse/ContentBrowseHierarchy.xml

<browse-hierarchy>
....

<browse-item id="xyzId"    label-resource="node.xxx.label"      is-root="true"   icon-resource="node.xxx.iconSmall">
     <list-definition id="allxxxx" xml-combine="remove" />
     <list-definition id="allxxxx"   retriever="query"  child-type="/atg/xxx/xxxs/xxxRepository:xxxRepItem" show-count-on-children="true" show-count-on-header="true">
      <retriever-parameter name="query"  value="ALL" />
    </list-definition>
  </browse-item>

...
</browse-hierarchy>

2)Versioned/config/atg/remote/content/find/ContentFindConfiguration.xml


<find-configuration site-filtering="true">
....

<asset-family id="xyzId" site-filtering="false">
 <display-name-resource>assetfamily.xyx.label</display-name-resource>
<enable-default-query>true</enable-default-query>
<enable-filter-as-you-type>true</enable-filter-as-you-type>
<result-list page-size="100" />
<default-asset-type>xxxRepItem</default-asset-type>


   <asset-type id="xxxId" site-filtering="false">
              <display-name-resource>assetfamily.xxx.yyy.label</display-name-resource>
              <enable-default-query>true</enable-default-query>
              <enable-filter-as-you-type>true</enable-filter-as-you-type>
              <repository-path>/atg/xxx/xxxs/xxxRepository</repository-path>
              <repository-item-type>xxxRepItem</repository-item-type>
        </asset-type>

</asset-family>


..........

</find-configuration>


3)src/com/xx/utils/XXContentRepositoryResources.properties

assetfamily.franchise.store.location.label=Franchise Store Location
assetfamily.franchise.store.label=Store


assetfamily.xxx.label=xxx Actual value
assetfamily.xxx.yyy.label = xx yy Actual Value

------------------------------------------------------------------------------

4) RepositoryAssetService

The following details helps to validate the property value which entered at BCC level.

Full path:Merchandising\config\atg\remote\assetmanager\editor\service\RepositoryAssetService.properties
RepositoryAssetService.properties
$class=com.xx.bcc.validation.XXPropertyValidator
propertyValidatorHelper=/com/xx/bcc/validation/XXPropertyValidatorHelper
productContextVo=/com/xx/remote/assetmanager/find/service/ProductContextVo

Usage of the component: In the customized class, doCreateAsset() method will populate the necessary info and then internall, it will call the OOTB method validateNewAsset(),then we can validate the data /ids .Using this ids query the other repository  and vierify
whether any items available or not.
Advantage.No need to map any repository item at BCC level, we can put the ids as form of string . and can verify here.



import atg.remote.assetmanager.AssetManagerResources;
import atg.remote.assetmanager.common.service.SecurityUtils;
import atg.remote.assetmanager.common.service.ServiceUtils;
import atg.remote.assetmanager.editor.service.AssetEditorInfo;
import atg.remote.assetmanager.editor.service.AssetServiceInfo;
import atg.remote.assetmanager.editor.service.CollectionPropertyServiceInfo;
import atg.remote.assetmanager.editor.service.RepositoryAssetServiceImpl;
import atg.repository.MutableRepository;
import atg.repository.MutableRepositoryItem;
import atg.repository.RepositoryException;
import atg.repository.RepositoryItem;
import atg.repository.RepositoryItemDescriptor;
import atg.service.asset.AssetUtils;
import atg.service.asset.RepositoryAssetWrapper;
import atg.servlet.ServletUtil;


public class XXPropertyValidator extends  RepositoryAssetServiceImpl{



//THe below method invoked both at the time of creation or updation.

public void doValidateAsset(AssetEditorInfo pEditorInfo, Collection pUpdates) {
validateXXXProperty(pEditorInfo, pUpdates);
// If there are no exception at form level, then OOTB method will be called.
if (!hasErrors()) {
super.doValidateAsset(pEditorInfo, pUpdates);
}
}
---- the custom method can be as follows.
This mehtod iterate the form fields of BCC. Whenver the required property encounters in the loop then
we will verify the property value as per requirement.
Then if the required value doesnot match, add the error. then we have to break the loop.
private void validateXXXProperty(AssetEditorInfo pEditorInfo, Collection pUpdatedItems) {
AssetViewUpdate updatedItem = null;
if (pUpdatedItems != null) {
Iterator iterUpdatedItems = pUpdatedItems.iterator();
while (iterUpdatedItems.hasNext()) {
updatedItem = (AssetViewUpdate) iterUpdatedItems.next();
}
PropertyEditorAssetViewUpdate propertyEditorTabUpdate = (PropertyEditorAssetViewUpdate) updatedItem;
Collection<PropertyUpdate> propertyUpdates = propertyEditorTabUpdate.getPropertyUpdates();
if (propertyUpdates != null) {
Iterator iterPropertyUpdates = propertyUpdates.iterator();

while (iterPropertyUpdates.hasNext()) {
PropertyUpdate propertyUpdate = (PropertyUpdate) iterPropertyUpdates.next();
String propertyName = propertyUpdate.getPropertyName();
String xxCategoryId = null;

if (propertyName.equals(getXxPropertyName())) { // getXxPropertyName() -- configured property name which we want to verify.
xxCategoryId = (String) propertyUpdate.getPropertyValue();
if (StringUtils.isNotBlank(xxCategoryId)) {
try {
RepositoryItem xxCategoryItem = getProductCatalog().getItem(xxCategoryId, getCategoryItemDescriptor());
if (xxCategoryItem == null) {
// getInvaidXXCategoryId()  -- return the configured  error msg to display at BCC.
addError(getInvaidXXCategoryId());
break;
}
} catch (RepositoryException e) {
}
}
break; }
}
}
}
}




//This method overrides doCreateAsset method to populate product id and product context, color, color translation flag is true.
//This method populate required data to be validate as part of validateNewAsset() method as show
public void doCreateAsset(AssetEditorInfo pEditorInfo, String pContainerPath, String pTypeName, String pParentAssetURI, String pLinkPropertyName, boolean pReverseLink){

 MutableRepository repository = (MutableRepository)ServiceUtils.getRepositoryFromNameOrPath(pContainerPath);
try{
        RepositoryItemDescriptor itemDescriptor = repository.getItemDescriptor(pTypeName);
           if (!(SecurityUtils.isCreatableType(itemDescriptor))) {
        String noPermissionError = AssetManagerResources.format("repAssetService.createPermissionDenied", ServletUtil.getCurrentRequest());

        addError(noPermissionError);
        return;
      }
           MutableRepositoryItem item = repository.createItem(pTypeName);

           ServiceUtils.updateUserDetails(item, "uiCreationUser");
      ServiceUtils.updateUserDetails(item, "uiLastModifiedUser");
      String uri = AssetUtils.createAssetURI(item);
      pEditorInfo.setAssetWrapper(new RepositoryAssetWrapper(item, uri));

      AssetServiceInfo assetInfo = (AssetServiceInfo)pEditorInfo.getAssetServiceData();
      assetInfo.setParentAssetURI(pParentAssetURI);
      assetInfo.setLinkPropertyName(pLinkPropertyName);
      assetInfo.setReverseLink(pReverseLink);

      if (pReverseLink) linkAsset(pEditorInfo);
} catch (Exception e)
    {
      String error = AssetManagerResources.format("repAssetService.errorCreatingItemOfType", pTypeName, ServletUtil.getCurrentRequest());

      addError(error);
      if (isLoggingError())
        logError(e);
    }


}


  //This is also OOTB method to valide new assets.As part of this OOTB method, we can invoke custome method.
     @Override
public void validateNewAsset(AssetEditorInfo pEditorInfo,Collection pUpdates) {
        //invoking the custom method to validate the data
validateXXXIds(pEditorInfo);
super.validateNewAsset(pEditorInfo, pUpdates);
}

}


//OOTB method invoking while updating the asset.As part of this OOTB method, we can invoke custome method.
@Override
public void validateUpdateAsset(AssetEditorInfo pEditorInfo,Collection pUpdates) {
validateXXXIds(pEditorInfo);
super.validateUpdateAsset(pEditorInfo, pUpdates);
}


//This method validate the property values(ids ) entered /provide by the BCC user and can verify with these ids any repository items available in .If not we can display error. Main aim is instead of associating the direcly repository item
// we can assoicate ids and can verify with these any items available in the system or not.
private void validateXXXIds(AssetEditorInfo pEditorInfo) {

String propertyName =null;
  RepositoryItem item = (RepositoryItem) pEditorInfo.getAssetWrapper().getAsset();

try{
     String itemDescriptor=item.getItemDescriptor().getItemDescriptorName();
     String propName =null;
     CollectionPropertyServiceInfo info=null;

info = (CollectionPropertyServiceInfo)pEditorInfo.getAssetPropertyServiceData().get("propertyName1");
if(info!=null && info.propertyValue.size()!=0){
propertyName="propertyName1";
}
       CollectionPropertyServiceInfo info = (CollectionPropertyServiceInfo)pEditorInfo.getAssetPropertyServiceData().get(propertyName);    
  for(int i=0; i<info.propertyValue.size();i++){
   String valueToConvert = (String) info.propertyValue.get(i);
   RepositoryItem repositoryItem=getSiteRepository().getItem(valueToConvert, getItemDescriptor());
   if(repositoryItem==null){
   invalidIds.add(valueToConvert);
   }
   }

           //if there are any invalid ids are there, then need to add error.
                if(!invalideSiteIds.isEmpty()){
        String errorMsg= getPropertyValidatorHelper().getErrorMessage(invalideSiteIds);
        addError(propName,errorMsg);
        }
} catch (RepositoryException e) {


   
}

}

----------------
5)BCC project creation  ,adding assets after modification and deploy the projects steps.


Component configuration
XXCreateBCCProjectCreation.properties

$class=com.xx.creatProject.XXCreateBCCProjectCreation.java
userAuthority=/atg/dynamo/security/UserAuthority
personaPrefix=Profile$login$
userName=admin
activity=merchandising.manageCommerceAssets

autoWorkflowName=/feed/autoworkflow.wdl
manualWorkflowName=/Common/commonWorkflow.wdl


Code in the XXCreateBCCProjectCreation.java

//imports
import atg.epub.project.ProcessHome;
import atg.epub.project.ProjectConstants;
import atg.nucleus.GenericService;
import atg.process.action.ActionConstants;
import atg.process.action.ActionException;
import atg.repository.RepositoryException;
import atg.repository.RepositoryItem;
import atg.security.Persona;
import atg.security.ThreadSecurityManager;
import atg.security.User;
import atg.userdirectory.UserDirectoryUserAuthority;
import atg.userprofiling.email.TemplateEmailException;
import atg.versionmanager.VersionManager;
import atg.versionmanager.WorkingContext;
import atg.versionmanager.Workspace;
import atg.workflow.ActorAccessException;
import atg.workflow.MissingWorkflowDescriptionException;
import atg.workflow.WorkflowConstants;
import atg.workflow.WorkflowException;
import atg.workflow.WorkflowManager;
import atg.workflow.WorkflowView;



private String mActivity;


//setter and getter
public UserDirectoryUserAuthority getUserAuthority() {
return mUserAuthority;
}

public void setUserAuthority(UserDirectoryUserAuthority pUserAuthority) {
mUserAuthority = pUserAuthority;

private VersionManager mVersionManager = null; 
/** property to hold WorkflowManager. */
private WorkflowManager mWorkflowManager = null; 
/** property to hold UserAuthority. */
private UserDirectoryUserAuthority mUserAuthority = null; 
/** property to hold PersonaPrefix. */
private String mPersonaPrefix = "Profile$login$";
/** property to hold UserName. */
private String mUserName = "admin"; 



/** property to hold WorkflowName. */
private String mAutoWorkflowName = "/Content Administration/import-staging.wdl";
/** The Manual workflow name. */
private String mManualWorkflowName = "/Content Administration/import-staging.wdl";
/** property to hold TaskOutcomeId. */
private String mTaskOutcomeId = "4.1.1"; 
}


public String getAutoWorkflowName() {
return this.mAutoWorkflowName;
}

public void setAutoWorkflowName(String pAutoWorkflowName) {
this.mAutoWorkflowName = pAutoWorkflowName;
}

public String getManualWorkflowName() {
return this.mManualWorkflowName;
}

public void setManualWorkflowName(String pManualWorkflowName) {
this.mManualWorkflowName = pManualWorkflowName;
}

public VersionManager getVersionManager() {
return mVersionManager;
}
public void setVersionManager(VersionManager pVersionManager) {
mVersionManager = pVersionManager;
}


public String getActivity() {
return this.mActivity;
}
public void setActivity(String pActivity) {
this.mActivity = pActivity;
}


public WorkflowManager getWorkflowManager() {
return mWorkflowManager;
}

public void setWorkflowManager(WorkflowManager pWorkflowManager) {
mWorkflowManager = pWorkflowManager;
}

/**
* This method unsets the security context on the current thread.
*/
protected void releaseUserIdentity() {
ThreadSecurityManager.setThreadUser(null);
}

public void createProject() throws RepositoryException{
1) UserIdentity
private UserDirectoryUserAuthority mUserAuthority = null;
User newUser = new User();
Persona persona = (Persona) getUserAuthority().getPersona(getPersonaPrefix() + getUserName());
// create a temporary User object for the identity
newUser.addPersona(persona);
// replace the current User object
  ThreadSecurityManager.setThreadUser(newUser);
Persona persona = (Persona) getUserAuthority().getPersona(getPersonaPrefix() + getUserName());

newUser.addPersona(persona); 
ThreadSecurityManager.setThreadUser(newUser);   

ProcessHome processHome = ProjectConstants.getPersistentHomes().getProcessHome();


if(isAutoWorkFlowEnabled()){
   process = processHome.createProcessForImport(pFileName, getAutoWorkflowName(), false);
  }else{
  process = processHome.createProcessForImport(pFileName, getManualWorkflowName(), false);
}

//getting the workspace name  and push development
String wkspNameFull = process.getProject().getWorkspace();
Workspace wksp = getVersionManager().getWorkspaceByName(wkspNameFull);
WorkingContext.pushDevelopmentLine(wksp);

  //write our custom code , like updating the reposiory items

  Set assets = process.getProject().getAssets();
  process.setActivity(mActivity);
  process.setDisplayName(process.getDisplayName() + "can add the assets size also here" );



  //advances the workflow to the next state

   /* If using an unaltered copy of the import-late or import-early
* workflows, then the taskOutcomeId property should not need to be changed (default is '4.1.1'). If you are using a
* different workflow or an altered version of the import-xxxx workflows, then the taskOutcomeId can be found in the wdl
* file for the respective workflow. */

   User newUser = new User();
Persona persona = (Persona) getUserAuthority().getPersona(getPersonaPrefix() + getUserName()); 

newUser.addPersona(persona); 
ThreadSecurityManager.setThreadUser(newUser);   

RepositoryItem processWorkflow = process.getProject().getWorkflow();
String workflowProcessName = processWorkflow.getPropertyValue("processName").toString();
String subjectId = process.getId();


try {
// an alternative would be to use the global workflow view at
if(ThreadSecurityManager.currentUser()!=null){
WorkflowView wv = getWorkflowManager().getWorkflowView(ThreadSecurityManager.currentUser());
wv.fireTaskOutcome(workflowProcessName, WorkflowConstants.DEFAULT_WORKFLOW_SEGMENT, subjectId, getTaskOutcomeId(),
ActionConstants.ERROR_RESPONSE_DEFAULT);
}

} catch (MissingWorkflowDescriptionException e) {
if (isLoggingError()){
vlogError(" Missing Workflow Description Exception ",e);
}
throw e;
} catch (ActorAccessException e) {
if (isLoggingError()){
vlogError(" Actor Access Exception ",e);
}
throw e;
} catch (ActionException e) {
if (isLoggingError()){
vlogError(" Action Exception ",e);
}
throw e;
} catch (UnsupportedOperationException e) {
if (isLoggingError()){
vlogError(" Unsupported Operation Exception ",e);
}
throw e;
} catch (Exception e) {
if(isLoggingError()){
vlogError("Exception",e);
}
} finally {
WorkingContext.popDevelopmentLine();
releaseUserIdentity();
}


  }

  }
-----------


6)Property descriptor implementation in ATG in BCC


If any property doesnot save any value in DB and just returned from custom logic, then we need to use the below logic.

In definition file(.xml file)

<property name="xxxProperty" data-type="string" property-type="com.xx.commerce.catalog.xxxPropertyDescriptor" readable="true"  display-name-resource="xxxx" writable="false">
</property>


Java classes

public class XXPropertyDescriptor extends RepositoryPropertyDescriptor {

private final VariableArgumentApplicationLogging mLogger = (VariableArgumentApplicationLogging) ClassLoggingFactory.getFactory().getLoggerForClass(AvailableInvDateForCAPropertyDescriptor.class);

  public Object getPropertyValue(RepositoryItemImpl pItem, Object pValue) {

  //te obtain any nucleus path, need to use below one.

   XXCLass xxObjt = (XXCLass) Nucleus.getGlobalNucleus().resolveName("componentPath");
  //do custom logic and retun the value

  }
}

7)Resolving  the issue related to repository mappings of xx repository 
which references a foreign customized non version price list repository.

The following classes and components are  implemented as part of this implementation

public class XXTargetDef extends atg.deployment.server.topology.TargetDef {

//Property to hold list of non version foreign repositories to ignore while validating repository mappings.
private Map<String,String> mNonVersionForeignRepositoriesToIgnore;
//Property to hold the topology manager instance
private XXTopologyManager mTopologyManager;

//constructor
protected XXTargetDef(atg.epub.project.TargetDef pDef)
{
super(pDef);
}

/**
* This constructor method sets the target definition and non version foreign repositories to ignore.
* @param pDef instance of TargetDef
* @param pNonVersionForeignRepositoriesToIgnore non version foreign repositories to ignore
* @param pTopologyManager instance of TopologyManager
*/
protected XXTargetDef(atg.epub.project.TargetDef pDef, Map<String,String> pNonVersionForeignRepositoriesToIgnore, XXTopologyManager pTopologyManager)
{
super(pDef);
this.mNonVersionForeignRepositoriesToIgnore = pNonVersionForeignRepositoriesToIgnore;
this.mTopologyManager = pTopologyManager;
}

@Override
public void validateRepositoryMappings() throws DeploymentException {

  Map<String,String> destinations = getDestinations();
if(destinations != null && mNonVersionForeignRepositoriesToIgnore != null){
destinations.putAll(mNonVersionForeignRepositoriesToIgnore);
}
   super.validateRepositoryMappings();
 
   if(destinations != null && mNonVersionForeignRepositoriesToIgnore != null){
for(String repositoryPath :  mNonVersionForeignRepositoriesToIgnore.keySet()){
destinations.remove(repositoryPath);
}
}
}

}

TopologyManager.properties
path :atg\epub\deployment\TopologyManager.properties

$class=com.xx.deployment.server.topology.XXTopologyManager
nonVersionForeignRepositoriesToIgnore=/atg/commerce/pricing/priceLists/PriceLists\=/atg/commerce/pricing/priceLists/PriceLists_production


/**
 * This class has been overridden to resolve the issue related to repository mappings of site repository
 * which references a foreign customized non version repositoryies like price list repository.
 */
public class XXTopologyManager extends TopologyManager{


// This member variable used to store the instance of TargetDefHome while starting this service.
private TargetDefHome mTargetDefHome;


//Property to hold list of non version foreign repositories to ignore while validating repository mappings.
   private Map<String,String> mNonVersionForeignRepositoriesToIgnore;
 

It is  overridden to store the instance of TargetDefHome in member variable mTargetDefHome while starting this service.
@throws ServiceException Service Exception
@Override
public void doStartService() throws ServiceException {
super.doStartService();
mTargetDefHome = ProjectConstants.getPersistentHomes().getTargetDefHome();
}


@Override
//It is overriden to create  customized instance of target XXTargetDef
public TargetDef createTarget() throws DeploymentException {
XXTargetDef targetDef = null;
try{
targetDef =  new XXTargetDef(mTargetDefHome.create(), getNonVersionForeignRepositoriesToIgnore(), this);
}catch (EJBException exp) {
throw new DeploymentException(exp);
} catch (CreateException exp) {
throw new DeploymentException(exp);
}

}

    return targetDef;
}

//This method has been overridden to create customized instance of target definition XXTargetDef
//@param pID target definition id
public TargetDef getTargetByID(String pID) throws DeploymentException {

XXTargetDef targetDef = null;
try
{
targetDef =  new XXTargetDef(mTargetDefHome.findByPrimaryKey(pID), getNonVersionForeignRepositoriesToIgnore(), this);
} catch (ObjectNotFoundException e) {
if(isLoggingError()){
logError(e);
}
} catch (EJBException exp) {
throw new DeploymentException(exp);
} catch (FinderException exp) {
throw new DeploymentException(exp);
}
   return targetDef;

}

public Map<String,String> getNonVersionForeignRepositoriesToIgnore() {
return mNonVersionForeignRepositoriesToIgnore;
}

public void setNonVersionForeignRepositoriesToIgnore(
Map<String,String> pNonVersionForeignRepositoriesToIgnore) {
this.mNonVersionForeignRepositoriesToIgnore = pNonVersionForeignRepositoriesToIgnore;
}

}

------------
8)Excel sheet Export Customization
This implementation is done to override generateExport which is used to inject parentCatergories property to export list for Product asset type.  To achieve this we Need to add the requried property names (to export in excel sheet) to the
existing list.

ExportEngine.properties

path:atg\remote\assetmanager\transfer\service\ExportEngine.properties

$class=com.xx.remote.assetmanager.transfer.service.XXExportEngine
loggingDebug=false
catalogTools=/atg/commerce/catalog/CatalogTools
productAsset=/atg/commerce/catalog/SecureProductCatalog:product
giftCardAsset=/atg/commerce/catalog/SecureProductCatalog:giftCard
productCollectionAsset=/atg/commerce/catalog/SecureProductCatalog:productCollection
additionalProp=\
parentCategories,\
productCollections,\
enabledCollectionCarousel


XXExportEngine.java

public class XXExportEngine extends ExportEngine {

/** The Constant PARENT_CATEGORIES. */
public static final String PARENT_CATEGORIES = "parentCategories";
/** The Additional prop. */
private List<String> mAdditionalProp = new ArrayList<String>();
/** The m product asset. */
private String mProductAsset;
/** The m gift card asset. */
private String mGiftCardAsset;
/** The m Product collection asset. */
private String mProductCollectionAsset;

public String getProductAsset() {
return this.mProductAsset;
}

public void setProductAsset(String pProductAsset) {
this.mProductAsset = pProductAsset;
}

public String getGiftCardAsset() {
return this.mGiftCardAsset;
}

public void setGiftCardAsset(String pGiftCardAsset) {
this.mGiftCardAsset = pGiftCardAsset;
}


public String getProductCollectionAsset() {
return this.mProductCollectionAsset;
}


public void setProductCollectionAsset(String pProductCollectionAsset) {
this.mProductCollectionAsset = pProductCollectionAsset;
}

public List<String> getAdditionalProp() {
return this.mAdditionalProp;
}


public void setAdditionalProp(List<String> pAdditionalProp) {
this.mAdditionalProp = pAdditionalProp;
}


  //This method is overriden to add the required property names  to exisiting list before exporting.

public boolean generateExport(String pAssetType, List<String> pAssetURIs, Object pSelectedInfo, String pExportFileFormat, String pMessageSubtopic) throws ExportException {
List propertyNames = null;
boolean useVerticalFormat = false;
if (pSelectedInfo instanceof AssetExportPropertyInfo) {
propertyNames = ((AssetExportPropertyInfo)pSelectedInfo).getAssetExportProperties();
useVerticalFormat = ((AssetExportPropertyInfo)pSelectedInfo).getUseVerticalFormat();
if((getProductAsset().equals(pAssetType) || getProductCollectionAsset().equals(pAssetType) || getGiftCardAsset().equals(pAssetType)) && "some boolean check at code level"){
vlogDebug("pAssetType - {0}", pAssetType);
if(getAdditionalProp() != null) {
propertyNames.addAll((List<String>)getAdditionalProp());
}
vlogDebug("propertyNames - {0}", propertyNames);
}
}

try
{
initializeContext(pAssetType, propertyNames, useVerticalFormat, pExportFileFormat);
} catch (TransferContextInitializationException ex) {
throw new ExportException(ex);
}

return generateExportPropertyExport(pAssetType, pAssetURIs, propertyNames, pExportFileFormat, pMessageSubtopic);
}

}


-------------------
9)Endeca workbench URL configuration  components
This component is overriden  to set the value of workbench public URL (if it is available) as workBench URL.

ApplicationConfiguration

path : \atg\endeca\ApplicationConfiguration.properties
$class=com.xx.endeca.XXApplicationConfiguration


XXApplicationConfiguration.java

import atg.endeca.configuration.ApplicationConfiguration;

/**
 * It  is extended to prepare the customized workbenchURL. If the public
 * work bench URL is available return this URL other wise return workBenchURL.
 */
public class xxApplicationConfiguration extends ApplicationConfiguration {

/** The work bench public url. */
private String mWorkBenchPublicURL;

/**
* Gets the work bench public url.
* @return the work bench public url
*/
public String getWorkBenchPublicURL() {
return this.mWorkBenchPublicURL;
}

/**
* Sets the work bench public url.
* @param pWorkBenchPublicURL the new work bench public url
*/
public void setWorkBenchPublicURL(String pWorkBenchPublicURL) {
this.mWorkBenchPublicURL = pWorkBenchPublicURL;
}
/**
* If workbench port number is 0 then host name will be set otherwise it
* will use existing flow only.
* @return the workbench URL
*/
@Override
public String getWorkbenchURL() {
if (!StringUtils.isBlank(getWorkBenchPublicURL())) {
return getWorkBenchPublicURL();
}
return super.getWorkbenchURL();
}

}


 10)Configuration for data-type="big string" for property of the ATG Repository for BCC fields.

 a)Newly created property:
   i)In this case simply declare  the data type of property as clob while adding itself.
  
  b)Modified existing property:    
    i)In this case if the existing property is not null then we have to do the following steps.
   First we have to add the column (placeHoderColomon_clob) to the table as data type clob as shown a)
   Next assign the existing column  to new column as b).
   Then drop existing column .
   Then rename the newly added column as e).
 
 
a)ALTER TABLE tableX ADD placeHoderColumn_clob clob;
b)UPDATE tableX SET placeHoderColumn_clob = existingColumn;
c)ALTER TABLE tableX DROP column existingColumn;
d)ALTER TABLE tableX RENAME column placeHoderColumn_clob to existingColumn;


11)

1 comment:

  1. Tech Solutions: At Bcc Customizations >>>>> Download Now

    >>>>> Download Full

    Tech Solutions: At Bcc Customizations >>>>> Download LINK

    >>>>> Download Now

    Tech Solutions: At Bcc Customizations >>>>> Download Full

    >>>>> Download LINK wl

    ReplyDelete