Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

[AEM][6.4][Upgrade]- Java servlet can't register on fresh 6.4 install and are in satisfied state

Avatar

Level 2

Hi Everyone,

I've been dealing with a issue on a fresh AEM 6.5 install. Some of my servlets/services cannot start. It can register fine and shows up okay however, it always throws a 404 at the path its registered at.

Has anyone ever seen? "Service factory returned null"

  1. 29.01.2019 10:09:08.144 *ERROR* [FelixDispatchQueue] com.adobe.wcm.wf-gtp-localization FrameworkEvent ERROR (org.osgi.framework.ServiceException: Service factory returned null. (Component: com.adobe.wcm.apps.gtp.services.impl.AnuvaadHelperServiceImpl (3417)))
  • org.osgi.framework.ServiceException: Service factory returned null. (Component: com.adobe.wcm.apps.gtp.services.impl.AnuvaadHelperServiceImpl (3417))

        at org.apache.felix.framework.ServiceRegistrationImpl.getFactoryUnchecked(ServiceRegistrationImpl.java:381)

        at org.apache.felix.framework.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:248)

        at org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:350)

        at org.apache.felix.framework.Felix.getService(Felix.java:3950)

Below is my sample code -

package com.adobe.wcm.apps.gtp.services.impl;

import static com.day.cq.commons.jcr.JcrConstants.JCR_DATA;

import static com.day.cq.commons.jcr.JcrConstants.MIX_LOCKABLE;

import static com.day.cq.commons.jcr.JcrConstants.NT_FILE;

import static com.day.cq.commons.jcr.JcrConstants.NT_FOLDER;

import static com.day.cq.commons.jcr.JcrConstants.NT_RESOURCE;

import static com.day.cq.commons.jcr.JcrConstants.NT_UNSTRUCTURED;

import static org.apache.sling.jcr.resource.api.JcrResourceConstants.AUTHENTICATION_INFO_SESSION;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Calendar;

import java.util.Collection;

import java.util.Collections;

import java.util.GregorianCalendar;

import java.util.HashMap;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

import javax.jcr.ItemNotFoundException;

import javax.jcr.Node;

import javax.jcr.NodeIterator;

import javax.jcr.PathNotFoundException;

import javax.jcr.RepositoryException;

import javax.jcr.Session;

import javax.jcr.Value;

import javax.jcr.ValueFactory;

import javax.jcr.ValueFormatException;

import com.adobe.wcm.apps.gtp.services.*;

import org.apache.commons.codec.binary.Base64;

import org.apache.commons.lang.StringUtils;

import org.apache.felix.scr.annotations.Activate;

import org.apache.felix.scr.annotations.Component;

import org.apache.felix.scr.annotations.Reference;

import org.apache.felix.scr.annotations.Service;

import org.apache.felix.scr.annotations.Services;

import org.apache.sling.api.SlingConstants;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.apache.sling.jcr.api.SlingRepository;

import org.json.simple.parser.ParseException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.adobe.granite.workflow.exec.WorkItem;

import com.adobe.wcm.apps.gtp.beans.AnuvaadErrorEmailInfo;

import com.adobe.wcm.apps.gtp.beans.AnuvaadErrorEmailInfo.AnuvaadWorkflow;

import com.adobe.wcm.apps.gtp.beans.AnuvaadProduct;

import com.adobe.wcm.apps.gtp.beans.LocaleNode;

import com.adobe.wcm.apps.gtp.constants.AssetLocaleStatus;

import com.adobe.wcm.apps.gtp.constants.AssetStatus;

import com.adobe.wcm.apps.gtp.constants.Constants;

import com.adobe.wcm.apps.gtp.constants.LocalizationConstants;

import com.adobe.wcm.apps.gtp.util.GetPropertiesFromPage;

import com.adobe.wcm.apps.gtp.util.Utils;

import com.day.cq.commons.jcr.JcrConstants;

import com.day.cq.commons.jcr.JcrUtil;

import com.day.cq.replication.Agent;

import com.day.cq.replication.ReplicationActionType;

import com.day.cq.replication.ReplicationException;

import com.day.cq.replication.ReplicationOptions;

import com.day.cq.replication.Replicator;

import com.day.cq.search.PredicateGroup;

import com.day.cq.search.Query;

import com.day.cq.search.QueryBuilder;

import com.day.cq.search.result.Hit;

import com.day.cq.search.result.SearchResult;

import com.day.cq.wcm.api.Page;

import com.day.cq.wcm.api.PageManager;

import com.day.cq.wcm.commons.ReferenceSearch;

import com.day.cq.workflow.WorkflowService;

import com.day.cq.workflow.WorkflowSession;

import com.day.cq.workflow.exec.Workflow;

import com.day.cq.workflow.exec.WorkflowData;

import com.day.cq.workflow.model.WorkflowModel;

@Component(immediate = true, metatype = true, label = "Anuvaad Helper Service", description = "Provides methods some helper methods for anuvaad")

@Services({ @Service(value = AnuvaadHelperService.class) })

public class AnuvaadHelperServiceImpl implements AnuvaadHelperService {

   private static final Logger LOGGER = LoggerFactory

  .getLogger(AnuvaadHelperService.class);

   private static final String publishWorkflowId = "/etc/workflow/models/anuvaad-publish-live/jcr:content/model";

   private static final String PROJECT_ROOT = "/etc/localization/projects";

   private static final String PRODUCT_NODE_TEMPLATE = "/apps/anuvaad/templates/jobCollection";

   private static final String JOB_NODE_TEMPLATE = "/apps/anuvaad/templates/job";

   private static final String JCR_CONTENT = "jcr:content";

   private static final String OKAPI_WF = "okapiWF";

   private static final String STUBGENERATED = "stubGenerated";

  

   private static final String MIX_ACCESS_CONTROLLABLE = "rep:AccessControllable";

   private static final String SLING_FOLDER = "sling:Folder";

   private static final String PATH_PROPERTY = "path";

   private GetPropertiesFromPage getImageObject = null;

  

   private static final String PRODUCT_LANGUAGE_MAPIING_ROOT_LEGACY = "/etc/localization/help/ProdLangMapping";

  

   private final static String PRODUCT_LANGUAGE_MAPIING_ROOT = "/etc/localization/help/ProdLangMapping/jcr:content";

   private String[] productList;

  

   private String[] topProductList;

   public static final String PRODUCTLIST_NEWOKAPI = "product.list";

  String[] exclusionPropertiesList;

  String[] urlFilterList;

  String[] templateList;

  

  String[] internalProducts;

  

  String[] internal;

  

   public static String helxpUrl = "http://helpx.stage.adobe.com";

  

   public static String emailAddress = "noreply@anuvaad-dev.com";

  @Reference

   protected SlingRepository repository;

  @Reference

   private Replicator replicator;

  

  @Reference

   protected WorkflowService workflowService;

  @Reference

   private QueryBuilder builder;

  @Reference

   protected GTPLocaleCodeMappingService gtplocalecodemappingservice;

  @Reference

   private WSLanguageService wsLangService;

  @Reference

   private AnuvaadConfigurationService anuvaadConfigurationService;

  @Reference

   private ResourceResolverFactory resolverFactory;

  @Reference

   private AnuvaadProductConfigService anuvaadProdConfService;

  @Reference

   private GlaasServiceImpl glaasSrvImpl;

  @org.apache.felix.scr.annotations.Property(label = "url.filters", value = {

   "&bsp;| ", "a|b" }, description = "List of filters ")

   private static final String DEFAULT_FILTER_PROPERTIES_LIST = "url.filters";

  @org.apache.felix.scr.annotations.Property(label = "template.list", value = {

   "help/components/pages/learn-explore", "help/components/pages/learn-creative-field" }, description = "List of templates not require publishing ")

   private static final String DEFAULT_TEMPLATE_LIST = "template.list";

  

  @org.apache.felix.scr.annotations.Property(label = "internal.products.list", value = {

   "/content/help/langmaster-replication/en/internal", "" }, description = "List of path of internal products ")

   private static final String DEFAULT_INTERNAL_PRODUCTS_LIST = "internal.products.list";

  

  @org.apache.felix.scr.annotations.Property(label = "Email address", value = { "noreply@adobe.com" }, description = "Email Address use to send email for Copy Workflow")

   private static final String DEFAULT_EMAIL_ADDRESS = "email.address";

  @org.apache.felix.scr.annotations.Property(label = "url.exclusion.propertyList", value = {

   "dummy|s1", "dumm1|b1" }, description = "List of Properties to exclude ")

   private static final String DEFAULT_EXCLUSION_PROPERTIES_LIST = "url.exclusion.propertyList";

  @org.apache.felix.scr.annotations.Property(label = "helpx.url", value = { "http://helpx.stage.adobe.com" }, description = "helpx url from which translations to be fetched ")

   private static final String DEFAULT_HELPX_URL = "helpx.url";

  @org.apache.felix.scr.annotations.Property(label = "product.okapi.list", value = {"a","b"}, description = "List of products for okapi workflow")

   private static final String PRODUCTLIST_NEWOKAPI_DEFAULT = "product.okapi.list";

  @org.apache.felix.scr.annotations.Property(label = "top.product.list", value = {"acrobat/11/","dreamweaver/","illustrator/", "indesign/", "photoshop/"}, description = "List of products for which more-help pages will be pushed to loc-author")

   private static final String TOP_PRODUCTLIST_NEWOKAPI_DEFAULT = "top.product.list";

  

  

  

   /**
  * {@inheritDoc}
  */
   @Override
   public String[] getGMSProductsForUser(String ldap) {

  String[] productsList = null;

  Map<String, String> map = new HashMap<String, String>();

  map.put("group.1_path", getProdLangMappingRoot());

  map.put("property", "ldap");

  map.put("property.value", ldap);

  map.put("p.hits", "full");

  map.put("p.limit", "-1");

  Session session = getRepositorySession();

   try {

  Query query = builder.createQuery(PredicateGroup.create(map),

  session);

  SearchResult result = query.getResult();

  List<Hit> hits = result.getHits();

  productsList = new String[hits.size()];

   int productCnt = 0;

   for (Hit hit : hits) {

  String nodePath = hit.getPath();

  productsList[productCnt++] = getProductNameFromPath(nodePath);

  }

  } catch (Exception e) {

   LOGGER.error("Anuvaad:Error in fetching the GMS products for ldap-"
   + ldap);

   LOGGER.error(Utils.getStackTraceAsString(e));

  } finally {

  session.logout();

  }

   return productsList;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String startRequiredWorkflow(String pagePath, String modelId) {

  Session newSession = getRepositorySession();

   if (newSession == null) {

   LOGGER.error("Anuvaad::Session is null. Cannot continue the workflow-["
   + modelId + "] for asset -" + pagePath);

   return null;

  }

   // Code to prevent running the publish workflow for stubGenerated pages.
   if (modelId.equals(publishWorkflowId)) {

   try {

  Node pageNode = newSession.getNode(pagePath);

   if (pageNode.hasNode("jcr:content")) {

  Node pageJcrNode = pageNode.getNode("jcr:content");

   if (pageJcrNode.hasProperty("stubGenerated")) {

  Boolean isStubGen = pageJcrNode.getProperty(

   "stubGenerated").getBoolean();

   if (isStubGen == true) {

   LOGGER.error("Page ["
   + pagePath

  + "] is stub generated. Terminating the republishing of this page");

   return null;

  }

  }

  }

  } catch (Exception e) {

   LOGGER.error("Anuvaad:Error in creating node or jcrNode from page ["
   + pagePath + "]");

   return null;

  }

  }

   LOGGER.debug("Starting the workflow with model-" + modelId

  + " on page-" + pagePath);

  WorkflowSession wfSession = workflowService
   .getWorkflowSession(newSession);

   try {

   // Get the workflow model
   WorkflowModel wfModel = wfSession.getModel(modelId);

   // Get the workflow data
  // The first param in the newWorkflowData method is the payloadType.
  // Just a fancy name to let it know what
  // type of workflow it is working with.
   WorkflowData wfData = wfSession.newWorkflowData("JCR_PATH",

  pagePath);

   // Run the Workflow.
   Workflow wf = wfSession.startWorkflow(wfModel, wfData);

   return wf.getId();

  } catch (Exception ex) {

   LOGGER.error("Anuvaad::Error in starting workflow -[" + modelId

  + "] for asset -" + pagePath);

   LOGGER.error(Utils.getStackTraceAsString(ex));

   return null;

  } finally {

  newSession.logout();

  }

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getWorkflowDataPath(String workflowId) {

  String[] tempArray = workflowId.split("/");

  String workflowDataPath = anuvaadConfigurationService
   .getWorkflowDataBasePath()

  + "/"
   + tempArray[5]

  + "/"
   + tempArray[6];

   return workflowDataPath;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getEmailAddress() {

   return this.emailAddress;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String[] getExclusionPropertiesList() {

   return this.exclusionPropertiesList;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String[] getAnuvaadLocaleListForGMSProduct(String GMSPrdName) {

  

  String path = getProdLangMappingRoot() + "/" + GMSPrdName + "/locales";

  

  

   if (GMSPrdName == null || GMSPrdName.length() == 0) {

   LOGGER.error("Anuvaad: getAnuvaadLocaleListForGMSProduct GMSProductName cannot be null or empty");

   return new String[0];

  }

  List<String> anuvaadLocaleList = new ArrayList<String>();

  Session session = getRepositorySession();

   try {

  Map<String, String> map = new HashMap<String, String>();

  map.put("group.1_path", path);

  map.put("property", "localeCode");

  List<Hit> hits = runQuery(map, session);

   for (Hit hit : hits) {

  Node node = hit.getNode();

   if (node.hasProperty("localeCode")) {

  String gmsLocale = node.getProperty("localeCode")

  .getString();

  List<String> langList = gtplocalecodemappingservice
   .getAdobeWebCodesForCountryCode(gmsLocale);

   if (langList.size() > 1) {

   LOGGER.debug("gmsLocale [" + gmsLocale

  + "] contains multiple locales in Web codes");

  }

  anuvaadLocaleList.addAll(langList);

  }

  }

  } catch (Exception e) {

   LOGGER.error("Anuvaad:Error in getting AnuvaadLocaleList for gmsProd-"
   + GMSPrdName);

   LOGGER.error(Utils.getStackTraceAsString(e));

  } finally {

  session.logout();

  }

   return anuvaadLocaleList.toArray(new String[anuvaadLocaleList.size()]);

  }

   @Override
   public String getProjectNameForGMSProduct(String GMSPrdName) {

  String path = getProdLangMappingRoot() + "/" + GMSPrdName + "/jcr:content";

   if (GMSPrdName == null || GMSPrdName.length() == 0) {

   LOGGER.error("Anuvaad: getAnuvaadLocaleListForGMSProduct GMSProductName cannot be null or empty");

   return "";

  }

  List<String> anuvaadLocaleList = new ArrayList<String>();

  Session session = getRepositorySession();

   try {

  Node productJCRNode = session.getNode(path);

   if(productJCRNode != null) {

   if (productJCRNode.hasProperty("projectName"))

   return productJCRNode.getProperty("projectName").getValue().toString();

  }

  } catch (Exception e) {

   LOGGER.error("Anuvaad:Error in getting AnuvaadLocaleList for gmsProd-"
   + GMSPrdName);

   LOGGER.error(Utils.getStackTraceAsString(e));

  } finally {

  session.logout();

  }

   return "";

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String[] getGMSLocaleListForGMSProduct(String GMSPrdName) {

  String path = getProdLangMappingRoot() + "/" + GMSPrdName + "/locales";

   if (GMSPrdName == null || GMSPrdName.length() == 0) {

   LOGGER.error("Anuvaad: getGMSLocaleListForGMSProduct GMSProductName cannot be null or empty");

   return new String[0];

  }

  List<String> anuvaadLocaleList = new ArrayList<String>();

  Session session = getRepositorySession();

   try {

  Map<String, String> map = new HashMap<String, String>();

  map.put("group.1_path", path);

  map.put("property", "localeCode");

  List<Hit> hits = runQuery(map, session);

   for (Hit hit : hits) {

  Node node = hit.getNode();

   if (node.hasProperty("localeCode")) {

  String gmsLocale = node.getProperty("localeCode")

  .getString();

  anuvaadLocaleList.add(gmsLocale.toLowerCase());

  }

  }

  } catch (Exception e) {

   LOGGER.error("Anuvaad:Error in getting GMSLocaleList for gmsProd-"
   + GMSPrdName);

   LOGGER.error(Utils.getStackTraceAsString(e));

  } finally {

  session.logout();

  }

   return anuvaadLocaleList.toArray(new String[anuvaadLocaleList.size()]);

  }

   /**
  * @param item
   * @param activeAssetsMap
   * @return
   */
   @Override
   public String getActiveAssetMap(String item,Map<String, Set<String>> activeAssetsMap) {

   try {

  String item_enxx = getENXXUrlPage(item);

   if(activeAssetsMap.containsKey(item_enxx))

  {

  Set<String> activeJobs = activeAssetsMap.get(item_enxx);

   if(activeJobs==null || activeJobs.isEmpty())

  {

   LOGGER.debug("Anuvaad: There are no active jobs for page : " + item);

   return null;

  }

  String formatedActvieJobs = "";

   for(String currentActivejobs : activeJobs)

  {

  formatedActvieJobs += currentActivejobs + ", ";

  }

   if(formatedActvieJobs.length() > 2)

  {

  formatedActvieJobs = formatedActvieJobs.substring(0, formatedActvieJobs.length()-2);

  }

   LOGGER.debug("Anuvaad: Active jobs for page " + item +" are " + formatedActvieJobs);

   return formatedActvieJobs;

  }

  } catch (Exception e) {

   LOGGER.error("Anuvaad: Error in generating en_xx url page for: " + item);

   LOGGER.error("Printing Stacktrace" + Utils.getStackTraceAsString(e));

  }

   return null;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public List<Hit> runQuery(Map<String, String> map, Session session) {

  map.put("p.hits", "full");

  map.put("p.limit", "-1");

   try {

  Query query = builder.createQuery(PredicateGroup.create(map),

  session);

  SearchResult result = query.getResult();

  List<Hit> hits = result.getHits();

   return hits;

  } catch (Exception e) {

   LOGGER.error("Anuvaad:Error in running Query for map-" + map);

   LOGGER.error(Utils.getStackTraceAsString(e));

  }

   return null;

  }

   /**
  *
  * @return A new admin session
  */

   private Session getRepositorySession() {

   try {

   return repository.loginAdministrative(null);

  } catch (RepositoryException e) {

   LOGGER.error("could not get repository session: ", e);

  }

   return null;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getProductNameFromAssetPath(String nodePath) {

  String[] splitedPath = nodePath.split("/");

   if (splitedPath.length > 4) {

   return splitedPath[4];

  }

   return "";

  }

   public String getProductNameFromPath(String nodePath) {

  String[] splitedPath = nodePath.split("/");

   if (splitedPath.length > 5) {

   if(anuvaadConfigurationService.getProdLangMappingFlag())

   return splitedPath[6];

   else
  return splitedPath[5];

  }

   return "";

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getAnuvaadPathFromProductName(String productName) {

  String nodePath = "";

  String contentPath = "/content/"
   + anuvaadConfigurationService.getApplicationPath();

  Map<String, String> map = new HashMap<String, String>();

  map.put("group.1_path", contentPath + "/en");

  map.put("property", "jcr:title");

  map.put("property.value", productName);

  map.put("p.nodedepth", "2");

  Session session = getRepositorySession();

   try {

  List<Hit> hits = runQuery(map, session);

   for (Hit hit : hits) {

  nodePath = hit.getPath();

   if (nodePath.contains("/jcr:content"))

  nodePath = nodePath.substring(0,

  nodePath.indexOf("/jcr:content"));

   return nodePath;

  }

  } catch (Exception e) {

   LOGGER.error("Anuvaad:Error in fetching anuvaad Product node name for product "
   + productName);

   LOGGER.error(Utils.getStackTraceAsString(e));

  } finally {

  session.logout();

  }

   return nodePath;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public Map<Node, Map<String, ArrayList<String>>> storeHODataInRepository(ResourceResolver resolver,

  Map<String, String> jobInfo, Map<String, String[]> assetLocaleData)

   throws Exception {

  String anuvaadProductName = jobInfo.get("cqProjectName");

  String jobName = jobInfo.get("jobName");

  String jobDescription = jobInfo.get(Constants.JOB_DESCRIPTION);

  String wfMetaDataPath = jobInfo.get("wfMetaDataPath");

  String dueDate = jobInfo.get("dueDate");

  String glaasProjectName = jobInfo.get(Constants.GLAAS_PROJECT_NAME);

  Calendar dueDateCalenderObject = Utils.getCalenderObject(dueDate, "dd/MM/yyyy");

   LOGGER.debug(String.format(

   "Anuvaad: Start creating a jobNode in schema for job [%s] ",

  jobName));

  Map<String, ArrayList<String>> failedAssetLocalesMap = new HashMap<String, ArrayList<String>>();

  Session session = resolver.adaptTo(Session.class);

  String userName = session.getUserID();

  PageManager pm = resolver.adaptTo(PageManager.class);

  String anuvaadProductKey = anuvaadProdConfService
   .getAnuvaadProductKeyForDisplayName(anuvaadProductName);

  Node jobNode = null;

   try {

  Node projectRoot = resolver.getResource(PROJECT_ROOT).adaptTo(

  Node.class);

  Node newProductPage;

   // Creating the product node if not already available
   if (!projectRoot.hasNode(anuvaadProductKey)) {

  newProductPage = pm.create(PROJECT_ROOT, anuvaadProductKey,

   PRODUCT_NODE_TEMPLATE, anuvaadProductKey).adaptTo(

  Node.class);

  Node jcrNode = newProductPage.getNode(JCR_CONTENT);

  jcrNode.getSession().save();

  } else {

  newProductPage = projectRoot.getNode(anuvaadProductKey);

  }

   // Creating the new jobNode
   Page newPage = pm.create(newProductPage.getPath(),

  jobName.replace(' ', '-'), JOB_NODE_TEMPLATE, jobName);

  Resource pageResource = newPage.getContentResource();

   if (pageResource != null) {

   // Setting the properties in jcr:content of jobNode
   Node node = pageResource.adaptTo(Node.class);

  node.setProperty(Constants.JOB_NAME, jobName);

  node.setProperty(Constants.JOB_INITIATER, userName);

  node.setProperty(Constants.JOB_DESCRIPTION, jobDescription);

  node.setProperty(Constants.WF_METADATA_PATH, wfMetaDataPath);

  node.setProperty(Constants.JOB_STATUS, Constants.STATUS_ACTIVE);

  node.setProperty(Constants.HO_DATE, Calendar.getInstance());

  node.setProperty(Constants.DUE_DATE, dueDateCalenderObject);

  node.setProperty(Constants.SOURCE_LANG, "en-US");

  node.setProperty(Constants.GLAAS_PROJECT_NAME,glaasProjectName );

   // Creating the new nodes per assets inside the jobNode
   jobNode = node.getParent();

   int i = 0;

   for (Entry<String, String[]> assetEntry : assetLocaleData

  .entrySet()) {

  Node resource = JcrUtil.createUniqueNode(jobNode,

   "resource" + "_" + i, "nt:unstructured",

  jobNode.getSession());

  ArrayList<String> failedLocales = setAssetAttributes(resolver, resource, assetEntry.getKey(),

  assetEntry.getValue());

  i++;

   if(failedLocales.size()>0)

  {

  failedAssetLocalesMap.put(assetEntry.getKey(), failedLocales);

  }

  }

  jobNode.getSession().save();

   LOGGER.debug(String

  .format("Anuvaad: Completed creating a jobNode in schema for job [%s] ",

  jobName));

  }

  Map<Node,Map<String, ArrayList<String>>> jobNodeFailedLocalesMap = new HashMap<Node, Map<String,ArrayList<String>>>();

  jobNodeFailedLocalesMap.put(jobNode, failedAssetLocalesMap);

   return jobNodeFailedLocalesMap;

  } catch (Exception e) {

   LOGGER.error("Anuvaad :Exception Occured:"
   + Utils.getStackTraceAsString(e));

  jobNode.getSession().refresh(false);

   return null;

  }

  }

   /**
  * Set the properties in the asset node inside job node
  *
  * @param resource
   * @param assetPath
   * @param localeList
   * @return
   * @throws Exception
  */

   private ArrayList<String> setAssetAttributes(ResourceResolver resolver, Node resource,

  String assetPath, String[] localeList) throws Exception {

   if (resource == null)

   return null;

  String[] images = getImageStrings(resolver, assetPath);

  String locNotes = getLocNotes(resolver, assetPath);

  String publishDate = getLocPublishDateFromPage(resolver.adaptTo(Session.class), assetPath);

  assetPath = assetPath.replace("/en/", "/en_xx/");

  resource.setProperty(Constants.ASSET_PATH, assetPath);

  resource.setProperty(Constants.ASSET_STATUS,

  AssetStatus.CREATED.getAssetStatusCode());

  resource.setProperty(Constants.ASSET_LOC_NOTES, locNotes);

  resource.setProperty(Constants.ASSET_PUBLISH_DATE, publishDate);

   if (images != null) {

  resource.setProperty(Constants.ASSET_IMAGES, images);

  } else {

  String[] emptyArray = new String[0];

  resource.setProperty(Constants.ASSET_IMAGES, emptyArray);

  }

   // Create nodes for locale list inside this asset node

   ArrayList<String> failedLocales = new ArrayList<String>();

   for (String locale : localeList) {

  WSLanguage wsLang = getWSLangFromWSWebCode(resolver, locale);

   if(wsLang==null)//unsupported locale encoutered. Skip current locale and send mail to Scrum
   {

  failedLocales.add(locale);

   continue;

  }

  String localeNodeName = wsLang.getWorldServerWebCode();//breaking here
   Node localeRes = JcrUtil.createUniqueNode(resource, localeNodeName,

   "nt:unstructured", resource.getSession());

  localeRes.setProperty(Constants.LOCALE_CODE, localeNodeName);

  localeRes.setProperty(Constants.ASSET_LOCALE_STATUS,

  AssetLocaleStatus.CREATED.getAssetStatusCode());

  localeRes.setProperty(Constants.PUBLISHED_PAGES, new String[0]);

  }

   // resource.getSession().save()
   return failedLocales;

  }

   /**
  * Returns the list of images in the page
  *
  * @param assetPath
   * @return
   */
   private String[] getImageStrings(ResourceResolver resolver, String assetPath) throws RepositoryException{

   if (assetPath == null)

   return null;

  Session session = resolver.adaptTo(Session.class);

  String[] imagesArray = getImageObject.getImagesInPage(session, builder,

  assetPath, resolver);

   if (imagesArray == null) {

   return null;

  }

   return imagesArray;

  }

  

  

  

  

   private String getLocNotes(ResourceResolver resolver, String assetPath) throws PathNotFoundException, RepositoryException{

   if(assetPath == null)

   return "";

  Session session = resolver.adaptTo(Session.class);

  Node pageJcrNode = session.getNode(assetPath+"/"+JcrConstants.JCR_CONTENT);

   if(pageJcrNode.hasProperty(Constants.LOC_NOTES)){

   return pageJcrNode.getProperty(Constants.LOC_NOTES).getString();

  }

   return "";

  }

   /**
  * {@inheritDoc}
  * @throws RepositoryException
  * @throws PathNotFoundException
  */
   @Override
   public String getLocPublishDateFromPage(Session session, String pagePath) throws PathNotFoundException, RepositoryException{

  Node pageJcrNode = session.getNode(pagePath).getNode(JcrConstants.JCR_CONTENT);

  String locPublishOption = "";

  String publishDate = Constants.PUBLISH_ASSET_ASAP;

   if(pageJcrNode.hasProperty(Constants.LOC_PUBLISH_OPTION)){

  locPublishOption = pageJcrNode.getProperty(Constants.LOC_PUBLISH_OPTION).getString();

   if(locPublishOption.equals(Constants.PUBLISH_LATER)){

   if(pageJcrNode.hasProperty(Constants.LOC_PUBLISH_DATE)){

  String date = pageJcrNode.getProperty(Constants.LOC_PUBLISH_DATE).getString();

   if(date.length() != 0){

  publishDate = date;

  }

  }

  }

  }

   return publishDate;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public WSLanguage getWSLangFromWSWebCode(ResourceResolver resolver,

  String wsWebCode) throws Exception {

  WSLanguage wsLang = wsLangService.getWSLanguage(resolver, wsWebCode);

   return wsLang;

  }

   /**
  * {@inheritDoc}
  */
   @SuppressWarnings("deprecation")

   @Override
   public Map<String, List<LocaleNode>> getAssetLocaleListMapFromJob(

  Node jobNode) throws RepositoryException, Exception {

  Map<String, List<LocaleNode>> assetLocaleMap = new HashMap<String, List<LocaleNode>>();

  NodeIterator iterator;

   try {

  iterator = jobNode.getNodes();

   while (iterator.hasNext()) {

  Node assetNode = iterator.nextNode();

   if (assetNode.getName().equals("jcr:content"))

   continue;

  String assetPath = assetNode.getProperty(Constants.ASSET_PATH)

  .getString();

  NodeIterator langNodeItr = assetNode.getNodes();

  List<LocaleNode> localeList = new ArrayList<LocaleNode>();

   while (langNodeItr.hasNext()) {

  Node langNode = langNodeItr.nextNode();

  LocaleNode newLocaleNode = new LocaleNode(

  langNode.getName(), langNode.getProperty(

  Constants.ASSET_LOCALE_STATUS).getString());

  WSLanguage wsLang = getWSLangFromWSWebCode(

   resolverFactory.getServiceResourceResolver(null), langNode.getName()

  .toLowerCase());

  newLocaleNode.setLocaleTitle(wsLang

  .getWorldServerWebCodeTitle());

  localeList.add(newLocaleNode);

  }

  assetLocaleMap.put(assetPath, localeList);

  }

  } catch (RepositoryException e) {

   LOGGER.error("Error in creating the asset locale list map for jobNode - "
   + jobNode.getPath());

   throw e;

  }

   return assetLocaleMap;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public Map<String, List<String>> getAssetImagesMapFromJob(Node jobNode)

   throws RepositoryException {

  Map<String, List<String>> assetImagesMap = new HashMap<String, List<String>>();

  NodeIterator iterator;

   try {

  iterator = jobNode.getNodes();

   while (iterator.hasNext()) {

  Node assetNode = iterator.nextNode();

   if (assetNode.getName().equals("jcr:content"))

   continue;

  String assetPath = assetNode.getProperty(Constants.ASSET_PATH)

  .getString();

  Value[] images = assetNode.getProperty(Constants.ASSET_IMAGES)

  .getValues();

  List<String> imageList = new ArrayList<String>();

   for (Value value : images) {

  imageList.add(value.getString());

  }

  assetImagesMap.put(assetPath, imageList);

  }

  } catch (RepositoryException e) {

   LOGGER.error("Error in creating the asset locale list map for jobNode - "
   + jobNode.getPath());

   throw e;

  }

   return assetImagesMap;

  }

   /**
  * {@inheritDoc}
  */
  //TODO To see if this can be moved to InitiateHoHelper class as mentioned in code review comments
   @Override
   public void updateJobStatus(Node jobNode, AssetLocaleStatus status)

   throws RepositoryException {

  NodeIterator itr = jobNode.getNodes();

   while (itr.hasNext()) {

  Node childNode = itr.nextNode();

   if (childNode.getPath().contains("jcr:content")) {

   continue;

  }

   if (childNode.hasProperty(Constants.ASSET_PATH)) {

  NodeIterator localeItr = childNode.getNodes();

   while (localeItr.hasNext()) {

  Node localeNode = localeItr.nextNode();

  localeNode.setProperty(Constants.ASSET_LOCALE_STATUS,

  status.getAssetStatusCode());

  }

  childNode.setProperty(Constants.ASSET_STATUS, AssetStatus.GMS_CREATED.getAssetStatusCode());

  }

  }

  jobNode.getSession().save();

  }

   /**
  * {@inheritDoc}
  */
  //TODO To see if this can be moved to InitiateHoHelper class as mentioned in code review comments
   @Override
   public String updateAssetStatus(Node jobNode, String assetPath,

  String targetLang, AssetLocaleStatus status) throws RepositoryException,

  IllegalArgumentException, Exception {

   LOGGER.debug("Anuvaad: updateAssetStatus : initialize");

   if(!assetPath.contains("langmaster-replication"))

  {

  assetPath = assetPath.replace("/content/help/", "/content/help/langmaster-replication/");

  }

  

  

  String productKey = jobNode.getParent().getName();

  AnuvaadProduct anPrd = anuvaadProdConfService.getAnuvaadProductForKey(productKey);

  String productName = anPrd.getDisplayName();

  

  

  String assetNodePath = getAssetNodePathFromJobPath(jobNode.getPath(),

  assetPath, jobNode.getSession());

  Node resourceNode = jobNode.getSession().getNode(assetNodePath);

  Node jcrContent = jobNode.getNode(JcrConstants.JCR_CONTENT);

  String jobName = jcrContent.getProperty(Constants.JOB_NAME).getString();

  String glassProjectName = "";

   if(jcrContent.hasProperty(Constants.GLAAS_PROJECT_NAME)){

  glassProjectName = jcrContent.getProperty(Constants.GLAAS_PROJECT_NAME).getString();

  }

   if (resourceNode.hasNode(targetLang.toLowerCase())) {

  Node targetLangNode = resourceNode

  .getNode(targetLang.toLowerCase());

  Long oldStatus = targetLangNode.getProperty(Constants.ASSET_LOCALE_STATUS)

  .getLong();

   if (status.getAssetStatusCode().equals( AssetLocaleStatus.CANCELLED
   .getAssetStatusCode())) { 

   if (!AssetLocaleStatus.isCancellable(oldStatus)) {

   throw new IllegalArgumentException(

   "Cannot update cancel status on a non-cancellable asset.");

  }

  }

  targetLangNode.setProperty(Constants.ASSET_LOCALE_STATUS,

  status.getAssetStatusCode());

  targetLangNode.getSession().save();

  }

   /*Check if a all assets are completed for the target Language.
  If completed then we need to call the glaas api to update the status of task to completed*/
   String langStatus = getLanguageStatusOfJob(jobNode, targetLang);

   if(langStatus.equals(Constants.GLAAS_TASK_CANCELLED) || langStatus.equals(Constants.GLAAS_TASK_COMPLETED)){

   glaasSrvImpl.updateTaskStatus(jobName, targetLang, langStatus,glassProjectName,productName);

  }

   // Also change the jobStatus to completed if job is completed
   String jobStatus = Constants.STATUS_ACTIVE;

   if (!status.isActive()) {

  jobStatus = getJobStatus(jobNode);

   if (jobStatus.equals(Constants.STATUS_COMPLETED)) {

   LOGGER.info("Anuvaad: updateAssetStatus : setting jobNode " + jobNode.getPath() + "Completed ");

  jobNode.getNode(JcrConstants.JCR_CONTENT).setProperty(

  Constants.JOB_STATUS, Constants.STATUS_COMPLETED);

  jobNode.getNode(JcrConstants.JCR_CONTENT).setProperty(

  Constants.COMPLETION_DATE, new GregorianCalendar());

  jobNode.getSession().save();

  }

  }

   return jobStatus;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getAssetNodePathFromJobPath(String jobNodePath,

  String assetPath, Session session) throws RepositoryException {

   LOGGER.debug("Anuvaad: getAssetNodePathFromJobPath : initialize");

   try {

  Node jobNode = session.getNode(jobNodePath);

  javax.jcr.NodeIterator childrenNodes = jobNode.getNodes();

  String childNodePath = null;

   while (childrenNodes.hasNext()) {

  Node childNode = childrenNodes.nextNode();

   LOGGER.debug("Anuvaad: resourceNode=" + childNode.getPath());

   if (childNode.getName().equalsIgnoreCase(JcrConstants.JCR_CONTENT)) {

   continue;

  }

   if (childNode.hasProperty(PATH_PROPERTY)) {

  childNodePath = childNode.getProperty(PATH_PROPERTY).getString();

   LOGGER.debug("Anuvaad: path in resourceNode=" + childNodePath);

   if (childNodePath.equals(assetPath)) {

   LOGGER.debug("Anuvaad: resource node path inside jobNode=" + childNode.getPath());

   return childNode.getPath();

  }

  } else {

   LOGGER.error(

   "Anuvaad: Error in getting path propety of the resource node at path " + childNodePath);

   throw new RepositoryException("Resource Node doesn't have the path property at path " + childNodePath);

  }

  }

  } catch (RepositoryException e) {

   LOGGER.error("Anuvaad: Error in getting resource Node path for Job node " + jobNodePath);

   throw e;

  }

   LOGGER.info("Anuvaad: No resource found with path property at the assest path " + assetPath + " for job node "
   + jobNodePath);

   return null;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public Set<String> getRefereesOfPage(Set<String> pagePaths, Session session)

   throws Exception {

  Set<String> setOfReferencedPages = new HashSet<String>();

   if (pagePaths.size() == 0) {

   return setOfReferencedPages;

  }

   try {

  String pathToSearch = "/content/"
   + anuvaadConfigurationService.getApplicationPath() + "/";

   LOGGER.debug("Anuvaad:Entering in getRefereesOfPage ");

  Map<String, String> map = new HashMap<String, String>();

  map.put("1_group.p.or","true");

  map.put("1_group.1_property", "path");

  map.put("1_group.1_property.operation", "like");

  map.put("1_group.2_property", "path");

  map.put("1_group.3_property", Constants.PROPERTY_HIGHLIGHTARTICLES);

  map.put("1_group.4_property", Constants.PROPERTY_PATHSFROMQUERY);

   int propertyIndex = 1;

   for (String path : pagePaths) {

  String propertyName1 = "1_group.1_property" + "."+ Integer.toString(propertyIndex) + "_" + "value";

  map.put(propertyName1, path + "/jcr:content%");

  String propertyName2 = "1_group.2_property" + "."+ Integer.toString(propertyIndex) + "_" + "value";

  map.put(propertyName2, path);

  String propertyName3 = "1_group.3_property" + "."+ Integer.toString(propertyIndex) + "_" + "value";

  map.put(propertyName3, path);

  String propertyName4 = "1_group.4_property" + "."+ Integer.toString(propertyIndex) + "_" + "value";

  map.put(propertyName4, path);

  propertyIndex++;

  }

  map.put("group.path", pathToSearch);

  List<Hit> result = runQuery(map, session);

   // iterating over the results and create set
   for (Hit hit : result) {

  String nodePath;

   try{

  nodePath = hit.getPath();

  nodePath = filterNodePath(nodePath, Constants.EMPTY);

  setOfReferencedPages.add(nodePath);

  }

   catch(ItemNotFoundException e){

   //Fix for bug in which publishing fails due to missing reference
   LOGGER.error("Expected:Not able to find a page in getReferees api for pagePaths "+pagePaths.toString());

  }

  }

  } catch (Exception e) {

   LOGGER.error(Utils.getStackTraceAsString(e));

   throw e;

  }

   LOGGER.debug("Anuvaad:Exiting the getRefereesOfPage api for pagePaths "
   + pagePaths.toString() + " Number of referenced pages is "
   + setOfReferencedPages.size());

   return setOfReferencedPages;

  }

   /**
  * get proper page path...remove unwanted elements such as mainpars and all
  * /jcr:content/main-pars/dynamicpod
  *
  * @param nodePath
   * @param replacement
   * @return
   */
   private String filterNodePath(String nodePath,

  String replacement) {

  String newNodePath = nodePath;

   try {

  newNodePath = nodePath.substring(0, nodePath.indexOf("/jcr:content"));

   LOGGER.error("Printing Node path" + nodePath );

  } catch (Exception e) {

  e.printStackTrace();

  }

   return newNodePath;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public boolean ifPropertyExists(Node baseNode, String property) {

   if (!property.contains("\\|"))

   return false;

  String[] propertySplit = property.split("\\|");

   if (propertySplit.length == 0) {

   LOGGER.debug("Anuvaad Helper service, String doesnt contains | ");

   return false;

  }

  String propertyName = propertySplit[0];

  String propertyValue = propertySplit[1];

   try {

   if (!baseNode.hasNode("jcr:content"))

   return false;

  Node jcrBaseNode = baseNode.getNode("jcr:content");

   if (jcrBaseNode.hasProperty(propertyName)) {

  javax.jcr.Property jcrNodeTitleProperty = jcrBaseNode

  .getProperty(propertyName);

  String jcrNodeTitle = jcrNodeTitleProperty.getString();

   if (jcrNodeTitle.equals(propertyValue))

   return true;

  }

  } catch (PathNotFoundException e) {

   LOGGER.error("Anuvaad PathNotFound exception ", e);

  } catch (ValueFormatException e) {

   LOGGER.error("Anuvaad valueformat exception ", e);

  } catch (RepositoryException e) {

   LOGGER.error("Anuvaad Repository exception ", e);

  }

   return false;

  }

  

   /**
  * @param path
   * @return
   * @throws Exception
  */
   @Override
   public String getKeyformPath(String path) throws Exception {

   if (path == null)

   return null;

  String key = null;

  String[] temp = path.split("\\/");

   if (temp != null) {

  key = temp[temp.length - 1];

  }

   if (key.endsWith(".html")) {

  String[] temp1 = key.split("\\.html");

  key = temp1[0]; // key is basically title of the link
   LOGGER.debug("Anuvaad: URL Pointer , Updated key is ", key);

  }

   return key;

  }

   /**
  * @param urlPage
   * @return
   * @throws Exception
  */
   @Override
   public String getENXXUrlPage(String urlPage) throws Exception {

   if(!urlPage.contains("help/langmaster-replication/")) {

   LOGGER.error("Anuvaad: Not able to get en_xx path from loc urlpage "
   + urlPage);

   return null;

  }

  String enXXUrlPage = urlPage.replaceAll("langmaster-replication/.*?/", "langmaster-replication/en_xx/");

   LOGGER.debug("Anuvaad: Printing en_xx path: " + enXXUrlPage);

   return enXXUrlPage;

  }

   /**
  * @param tiPage
   * @return
   * @throws Exception
  */
   @Override
   public String getHelpxUrl(String tiPage, String helpxUrl) throws Exception {

   if (tiPage == null || !tiPage.startsWith("/content/help"))

   return "";

  String helpxTIPage = "";

   int beginIndex = tiPage.indexOf("/content/help/langmaster-replication/");

   int endIndex = tiPage.indexOf("/jcr:content/main-pars/dynamicpod");

  helpxTIPage = tiPage.substring(beginIndex, endIndex);

  helpxTIPage = helpxUrl + helpxTIPage + ".html";

   return helpxTIPage;

  }

   /**
  * {@inheritDoc}
  */
   public String getJobStatus(Node jobNode) throws Exception {

  NodeIterator itr = jobNode.getNodes();

   while (itr.hasNext()) {

  Node childNode = itr.nextNode();

   if (childNode.getName().equals(JcrConstants.JCR_CONTENT)) {

   continue;

  }

  NodeIterator localeNodeItr = childNode.getNodes();

   boolean ifPublished = false;

   while (localeNodeItr.hasNext()) {

  Node localeNode = localeNodeItr.nextNode();

  Long status = localeNode.getProperty(Constants.ASSET_LOCALE_STATUS)

  .getLong();

   int assetStatus = status.intValue();

   if (assetStatus == AssetLocaleStatus.CREATED.getAssetStatusCode()

  || assetStatus == AssetLocaleStatus.GMS_CREATED
   .getAssetStatusCode()

  || assetStatus == AssetLocaleStatus.IMPORT_COMPLETED
   .getAssetStatusCode()) {

   LOGGER.info("Anuvaad: getJobStatus : resource Node is active since on of the locale node " + localeNode.getPath() + " has ASSET LOCALE STATUS " + assetStatus);

   return Constants.STATUS_ACTIVE;

  }

   if(assetStatus==AssetLocaleStatus.PUBLISH_SUBMIT.getAssetStatusCode())

  {

  ifPublished=true;

  }

  }

   if(ifPublished==false)

  {

   LOGGER.info("Anuvaad: getJobStatus : setting resource Node " + childNode.getPath() + "Cancelled ");

  childNode.setProperty(Constants.ASSET_STATUS, AssetStatus.CANCELLED.getAssetStatusCode());

   continue;

  }

   LOGGER.info("Anuvaad: getJobStatus : setting resource Node " + childNode.getPath() + "Completed ");

  childNode.setProperty(Constants.ASSET_STATUS, AssetStatus.COMPLETED.getAssetStatusCode());

  }

   // If Status is not active then it would be completed
   LOGGER.info("Anuvaad: getJobStatus : setting jobNode " + jobNode.getPath() + "Completed ");

   return Constants.STATUS_COMPLETED;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public void resetReadyForLocalizationFlag(Session session,

  String assetPath, boolean flag) {

   try {

  Node rootNode = session.getRootNode();

  assetPath = assetPath.replace("/en_xx/", "/en/");

  String assetNodePath = assetPath.substring(1);

  Node assetNode = rootNode.getNode(assetNodePath).getNode(

   "jcr:content");

  assetNode.setProperty("isReadyForLocalization", flag);

  assetNode.getSession().save();

  rootNode.getSession().save();

  } catch (RepositoryException e) {

   LOGGER.error(String

  .format("Error in reseting ready for localization flag for asset [%s]",

  assetPath));

   LOGGER.error(Utils.getStackTraceAsString(e));

  }

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public void resetImageStatusFlag(Session session, String assetPath)

   throws PathNotFoundException {

   try {

  String assetContentPath = assetPath.replaceFirst("/", "");

  assetContentPath = assetContentPath + "/jcr:content/main-pars";

  String[] tempPaths = assetContentPath.split("content/help/langmaster-replication/en/");

  String articleName = tempPaths[1]; // instead article name give path
  // after en
   articleName = articleName

  .replaceFirst("/jcr:content/main-pars", "");

  String nameInGlobalList = Constants.IMAGE_GLOBALROOTPATH
   + articleName;

   // updateImagesStatusInContentRepo(session,assetContentPath);
   nameInGlobalList = nameInGlobalList.replaceFirst("/", "");

   updateImagesStatusInGlobalImageList(session, nameInGlobalList);

  } catch (Exception e) {

  Utils.getStackTraceAsString(e);

  }

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public AnuvaadErrorEmailInfo getErrorEmailInfoFromJobNode(Node node, String assetPath, AnuvaadWorkflow workflow){

  AnuvaadErrorEmailInfo emailInfo = new AnuvaadErrorEmailInfo();

   if (workflow!=null) {

  emailInfo.setWorkflow(workflow);

  }

   if (node !=null) {

   try {

  NodeIterator iter = node.getNodes("jcr:content");

  Node jcrContent = null;

   if(iter.hasNext()) {

  jcrContent = iter.nextNode();

  }

   if(jcrContent!=null) {

  String jobName = jcrContent.getProperty(Constants.JOB_NAME).getString();

   // Since in a jobName the string till the first _ is productName
   String productName = jobName.split("_")[0];

  emailInfo.setHoName(jobName);

  emailInfo.setProductName(productName);

  }

  } catch (RepositoryException e) {

   LOGGER.warn("Could not populate information in Anuvaad Error Email Info Object due to repository exception.",e);

  }

  }

   if (assetPath!=null) {

  emailInfo.setPath(assetPath);

  String productNameFromAssetPath ="";

   // Fetch product name from config
   Set<AnuvaadProduct> products = anuvaadProdConfService.getAnuvaadProductMatches(assetPath);

   if (products.size() == 1) {

   for (AnuvaadProduct product: products){

  productNameFromAssetPath = product.getDisplayName();

  }

  }

   if (productNameFromAssetPath != null && productNameFromAssetPath.length() > 0) {

  emailInfo.setProductName(productNameFromAssetPath);

  }

  }

   return emailInfo;

  }

   /**
  * This updates the status of the given images in global image repository.
  *
  * @param session
   * @param nameInGlobalList
   * @throws RepositoryException
  */
   private static void updateImagesStatusInGlobalImageList(Session session,

  String nameInGlobalList) throws RepositoryException {

  Node rootNode;

  rootNode = session.getRootNode();

   if (rootNode.hasNode(nameInGlobalList)) {

  Node assetNode = rootNode.getNode(nameInGlobalList);

   if (assetNode.hasNodes()) {

  NodeIterator child = assetNode.getNodes();

   while (child.hasNext()) {

  Node childNode = child.nextNode();

   if (childNode.hasNode("jcr:content")) {

  Node jcrImageNode = childNode.getNode("jcr:content");

  jcrImageNode.setProperty(Constants.IMAGE_STATUS,

  Constants.IMAGE_TRANSLATIONINPROGRESS);

  }

  }

  }

  }

  session.save();

  }

   /**
  * @param session
   * @param prodKey
   * @return
   */
   public Map<String, Set<String>> initializeActiveAssetsMap(Session session,String prodKey) {

  GetPropertiesFromPage gip = new GetPropertiesFromPage();

  String productPath = "/etc/localization/projects/" + prodKey;

  String[] productPathList = new String[] {productPath};

  Map<String, Set<String>> activeAssetsMap = null;

  activeAssetsMap = gip.getActiveAssetsMap(productPathList, session, builder,this);

   return activeAssetsMap;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getWSWebCodeFromAdobeWebCode(String adobeWebCode){

  WSLanguage wsLang = gtplocalecodemappingservice.getWSLangFromWebCode(adobeWebCode);

   if(wsLang != null){

   //return wsLang.getWorldServerWebCode();
  //MSM should return ISO code instead of worldserver web code.
   return wsLang.getIsoLanguageCode();

  }

   else{

   return "";

  }

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String[] getURLFilters() {

   return urlFilterList;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String[] getTemplateList() {

   return templateList;

  }

  

  

   /**
  * {@inheritDoc}
  */
   @Override
   public String[] getInternalProductList() {

   return internalProducts;

  }

  @Activate

   protected void activate(final Map<String, Object> config) {

  Map<String, Object> properties = config != null ? config : Collections

  .<String, Object> emptyMap();

   try {

   productList = (String[]) properties.get(PRODUCTLIST_NEWOKAPI_DEFAULT);

   topProductList = (String[]) properties.get(TOP_PRODUCTLIST_NEWOKAPI_DEFAULT);

   emailAddress = (String) properties.get(DEFAULT_EMAIL_ADDRESS);

   helxpUrl = (String) properties.get(DEFAULT_HELPX_URL);

   exclusionPropertiesList = (String[]) properties

  .get(DEFAULT_EXCLUSION_PROPERTIES_LIST);

   urlFilterList = (String[]) properties

  .get(DEFAULT_FILTER_PROPERTIES_LIST);

   templateList = (String[]) properties

  .get(DEFAULT_TEMPLATE_LIST);

   internalProducts = (String[]) properties

  .get(DEFAULT_INTERNAL_PRODUCTS_LIST);

   getImageObject = new GetPropertiesFromPage();

  } catch (Exception e) {

   LOGGER.error("Error Anuvaad Helper service Impl", e);

  }

   LOGGER.info("Anuvaad Helper Service has been configured with following values.");

   LOGGER.info("productList = {}", Arrays.toString(productList));

   LOGGER.info("MoreHelp productList = {}", Arrays.toString(topProductList));

   LOGGER.info("exclusionPropertiesList = {}", Arrays.toString(exclusionPropertiesList));

   LOGGER.info("urlFilterList = {}", Arrays.toString(urlFilterList));

   LOGGER.info("templateList = {}", Arrays.toString(templateList));

   LOGGER.info("emailAddress = {}", emailAddress);

   LOGGER.info("helxpUrl = {}", helxpUrl);

  

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public List<String> getStakeHolderforProduct(Session session, String productConfigPath) throws PathNotFoundException, RepositoryException {

  Node productConfNode = session.getNode(productConfigPath);

  AnuvaadProduct aProd = new AnuvaadProduct(productConfNode);

  String gmsProductName = aProd.getGmsProductName();

  Node stakeHolderNode = null;

  

  String stakeHolderNodePath;

  stakeHolderNodePath = getProdLangMappingRoot() + "/" + gmsProductName + "/StakeHolders";

   if(session.itemExists(stakeHolderNodePath))

  {

  stakeHolderNode = session.getNode(stakeHolderNodePath);

  }

   else
   {

   LOGGER.error("Unable to get StakeHolderNode at " + stakeHolderNodePath);

   return null;

  }

  NodeIterator stakeHolders = stakeHolderNode.getNodes();

  List<String> stakeHolderList = new ArrayList<String>();

   while(stakeHolders.hasNext())

  {

  stakeHolderList.add(stakeHolders.nextNode().getNode("jcr:content").getProperty("email").getString());

  }

   return stakeHolderList;

  }

   /**
  * {@inheritDoc}
  * @throws RepositoryException
  */
   public List<String> getLocaleListFromJobNode(Node jobNode) throws RepositoryException{

  Set<String> localeSet = new HashSet<String>();

  NodeIterator iterator;

   try {

  iterator = jobNode.getNodes();

   while (iterator.hasNext()) {

  Node assetNode = iterator.nextNode();

   if (assetNode.getName().equals("jcr:content"))

   continue;

  String assetPath = assetNode.getProperty(Constants.ASSET_PATH)

  .getString();

  NodeIterator langNodeItr = assetNode.getNodes();

  List<LocaleNode> localeList = new ArrayList<LocaleNode>();

   while (langNodeItr.hasNext()) {

  Node langNode = langNodeItr.nextNode();

  localeSet.add(langNode.getName());

  }

  }

  } catch (RepositoryException e) {

   LOGGER.error("Error in creating the asset locale list map for jobNode - "
   + jobNode.getPath());

   throw e;

  }

  List<String> localeList = new ArrayList<String>(localeSet);

   return localeList;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public boolean checkIfOkapiEnabled(String product)

  {

   for(String prod:productList)

  {

   if(prod.equalsIgnoreCase(product))

  {

   return true;

  }

  }

   return false;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public boolean topProduct(String page)

  {

  String path = "";

   LOGGER.debug("printing page " + page);

  String[] split = page.split("/content/help/langmaster-replication/");

   if (split.length == 0) {

   LOGGER.error("Anuvaad: Not able to get path from loc urlpage "
   + page);

   return false;

  } else {

  String tempPath = split[1];

   LOGGER.debug("printing temppath " + tempPath);

  path = tempPath.substring(tempPath.indexOf("/", 1));

   LOGGER.debug("printing path " + path);

  }

  

   for(String prod:topProductList)

  {

   LOGGER.debug("printing prod " + prod);

   if(path.startsWith(prod))

  {

   LOGGER.debug("found a top product " + prod);

   return true;

  }

  }

   LOGGER.debug("Not a top product " );

   return false;

  }

  

  

   /**
  * {@inheritDoc}
  */
   @Override
   public ArrayList<Node> getPropertyNodesRecursively(String path, List<String> propertyValue, ArrayList<Node> nodeList)

  {

   try{

  Node node = null;

  Session session = getRepositorySession();

   if(!session.itemExists(path))

  {

   LOGGER.debug("Page doesn't exists " + path);;

   return nodeList;

  }

   else
   {

  node = session.getNode(path);

  NodeIterator iter = node.getNodes();

   while (iter.hasNext())

  {

  Node childNode = iter.nextNode();

   boolean propertyExist = propertyExist(childNode, propertyValue);

   if(propertyExist)

  {

   if(nodeList==null)

  {

  nodeList = new ArrayList<Node>();

  }

  nodeList.add(childNode);

  }

   if(childNode.hasNodes())

  {

  NodeIterator childIter = childNode.getNodes();

   while(childIter.hasNext())

  {

  Node children = childIter.nextNode();

  nodeList = getPropertyNodesRecursively(children.getPath(), propertyValue, nodeList);

  }

  }

  }

  }

  }catch(Exception e)

  {

   LOGGER.error(String

  .format("Error in searching properties in page"));

   LOGGER.error(Utils.getStackTraceAsString(e));

  }

   return nodeList;

  }

   private boolean propertyExist(Node childNode,

  List<String> propertyValue) {

   try
   {

   for(String value: propertyValue)

  {

   if(childNode.hasProperty(LocalizationConstants.SLING_RESOURCETYPE_PROPERTYNAME))

  {

   if(childNode.getProperty(LocalizationConstants.SLING_RESOURCETYPE_PROPERTYNAME).getString().equals(value))

  {

   return true;

  }

  }

  }

  }

   catch(Exception e)

  {

   LOGGER.error(String

  .format("Error in searching properties in page. Exception occured while checking property exists"));

   LOGGER.error(Utils.getStackTraceAsString(e));

  }

   return false;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public boolean checkPageType(

  String asset, Session jcrSession, String slingResourceType) {

   try{

   if(jcrSession.itemExists(asset))

  {

  Node pageNode = jcrSession.getNode(asset);

   if (pageNode.hasNode("jcr:content")) {

  Node pageJcrNode = pageNode.getNode("jcr:content");

   if(pageJcrNode.hasProperty("sling:"+SlingConstants.PROPERTY_RESOURCE_TYPE)){

  String resType = pageJcrNode.getProperty("sling:"+SlingConstants.PROPERTY_RESOURCE_TYPE).getString();

   if(resType.equals(slingResourceType)){

   return true;

  }

  }

  }

  }

  }catch(Exception e)

  {

   LOGGER.error(String

  .format("Error in checking page type of the page " + asset));

   LOGGER.error(Utils.getStackTraceAsString(e));

  }

   return false;

  }

   /**
  * {@inheritDoc}
  */
   public Set<String> getRequiredRenditions(String assetPath,Session session) throws Exception{

  Set<String> renditions = new HashSet<String>();

   //.txt and .html in case of HelpMap
   if(checkPageType(assetPath, session, Constants.HELP_MAP)){

  renditions.add(assetPath + ".txt");

  }

   //.ccx.html and .html in case of how-to(learn-content)
   else if(checkPageType(assetPath, session, Constants.LEARN_CONTENT)){

  renditions.add(assetPath+".ccx.html");

  renditions.add(assetPath + ".html");

  }

   //.js in case of learn-tutorial, ccx-cards and product-details
   else if(checkPageType(assetPath, session, Constants.HELP_COMPONENTS_PAGES_LEARN_TUTORIALS) ||

  checkPageType(assetPath, session, Constants.CCX_CARDS) ||

  checkPageType(assetPath, session, Constants.PRODUCT_DETAILS)){

  renditions.add(assetPath+".js");

  }

   //.ccx.js and .js in case of learn-home
   else if(checkPageType(assetPath, session, Constants.HELP_COMPONENTS_PAGES_LEARN_HOME)){

  renditions.add(assetPath+".ccx.js");

  renditions.add(assetPath+".js");

  }

   //.js for ccx-cards-collection
   else if(checkPageType(assetPath, session, Constants.CCX_CARDS_COLLECTION)){

  renditions.add(assetPath+".js");

  }

   //.html for all others
   else{

  renditions.add(assetPath + ".html");

  }

   return renditions;

  }

   /**
  * {@inheritDoc}
  */
   public String getDefaultRendition(String assetPath,Session session) throws Exception{

   //.txt in case of HelpMap
   if(checkPageType(assetPath, session, Constants.HELP_MAP)){

   return ".txt";

  }

   //.js in case of learn-tutorial, ccx-cards,product-details,learn-home, ccx-cards-collection
   else if(checkPageType(assetPath, session, Constants.HELP_COMPONENTS_PAGES_LEARN_TUTORIALS) ||

  checkPageType(assetPath, session, Constants.CCX_CARDS) ||

  checkPageType(assetPath, session, Constants.PRODUCT_DETAILS) ||

  checkPageType(assetPath, session, Constants.HELP_COMPONENTS_PAGES_LEARN_HOME) ||

  checkPageType(assetPath, session, Constants.CCX_CARDS_COLLECTION)){

   return ".js";

  }

   //.html for all others
   return ".html";

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getOkapiWF(String jobNodePath, boolean newPage)

  {

   if(newPage)

  {

   return LocalizationConstants.STANDARD_OKAPI;

  }

   else
   {

  String product = getProductTitleFromJobPath(jobNodePath);

   if(checkIfOkapiEnabled(product))

  {

   return LocalizationConstants.STANDARD_OKAPI;

  }

   else
   {

   return LocalizationConstants.CUSTOMIZED_OKAPI;

  }

  }

  }

   private String getProductTitleFromJobPath(String jobNodePath) {

  String product = null;

   try {

  Session session = getRepositorySession();

   if(session.itemExists(jobNodePath))

  {

  Node projectNode;

  projectNode = session.getNode(jobNodePath);

  Node product_Node = projectNode.getParent();

   if(product_Node.hasNode("jcr:content"))

  {

  Node projectJcrNode = product_Node.getNode("jcr:content");

  product = projectJcrNode.getProperty("jcr:title").getString();

  }

  }

  }

   catch (PathNotFoundException e) {

   LOGGER.error(Utils.getStackTraceAsString(e));

  } catch (RepositoryException e) {

   LOGGER.error(Utils.getStackTraceAsString(e));

  }

   return product;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getAssetsOkapiWfList(Session session, Set<String> assets, Node jobNode) throws ParseException, RepositoryException {

  String assetsOkapiList="";

   for(String asset : assets)

  {

  String asset_enxx = "";

   if(asset.contains("/en/"))

  {

  asset_enxx = asset.replace("/en/", "/en_xx/");

  }

   if(!asset_enxx.equals(""))

  {

   boolean newPage = checkNewPage(session, asset_enxx);

  String okapiWF = getOkapiWF(jobNode.getPath(), newPage);

  assetsOkapiList += asset_enxx + "::" + okapiWF + ",";

  }

  }

   return assetsOkapiList;

  }

   private boolean checkNewPage(Session session, String asset_enxx) throws RepositoryException {

   if(!session.itemExists(asset_enxx))

   return true;

  Node assetNode = session.getNode(asset_enxx);

   if(assetNode.hasNode("jcr:content") && assetNode.getNode("jcr:content").hasProperty(STUBGENERATED) && assetNode.getNode("jcr:content").getProperty(STUBGENERATED).getBoolean())

  {

   return true;

  }

   if(assetNode.hasNode("jcr:content") && assetNode.getNode("jcr:content").hasProperty(OKAPI_WF) && assetNode.getNode("jcr:content").getProperty(OKAPI_WF).getString().equalsIgnoreCase("true"))

  {

   return true;

  }

   return false;

  }

   private String getLanguageStatusOfJob(Node jobNode, String targetLang) throws RepositoryException{

  NodeIterator itr = jobNode.getNodes();

  Boolean isCompleted = false;

   while (itr.hasNext()) {

  Node childNode = itr.nextNode();

   if (childNode.getName().equals(JcrConstants.JCR_CONTENT)) {

   continue;

  }

   if(childNode.hasNode(targetLang.toLowerCase())){

  Node localeNode = childNode.getNode(targetLang.toLowerCase());

  Long status = localeNode.getProperty(Constants.ASSET_LOCALE_STATUS)

  .getLong();

   int assetStatus = status.intValue();

   if (assetStatus == AssetLocaleStatus.CREATED.getAssetStatusCode()

  || assetStatus == AssetLocaleStatus.GMS_CREATED
   .getAssetStatusCode()

  || assetStatus == AssetLocaleStatus.IMPORT_COMPLETED
   .getAssetStatusCode()) {

   return Constants.GLAAS_TASK_CREATED;

  }

   //Mark isCompleted true if at least one of asset is completed
   if(assetStatus == AssetLocaleStatus.PUBLISH_SUBMIT.getAssetStatusCode()){

  isCompleted = true;

  }

  }

  }

   // If at least 1 asset is completed then return "COMPLETED" else return "CANCELLED"
   if(isCompleted)

   return Constants.GLAAS_TASK_COMPLETED;

   return Constants.GLAAS_TASK_CANCELLED;

  }

   /**
  * Generates publishExternalURL of the given node.
  * @param pageNode
   * @return
   * @throws RepositoryException
  */
   @Override
   public String getPublishExternalURL ( Node pageNode ) throws RepositoryException

  {

  String pagePath = "";

  String server = Constants.EXTERNAL_LOADBALANCER_URL;

  String jcrLanguage = "";

   if(pageNode.hasNode(Constants.JCRCONTENT))

  {

  Node pageJcrNode = pageNode.getNode(Constants.JCRCONTENT);

   if(pageJcrNode.hasProperty("jcr:language"))

  {

  jcrLanguage = pageJcrNode.getProperty("jcr:language").getString();

  }

  }

  

  pagePath = pageNode.getPath();

   if (pagePath.contains("langmaster-replication"))

   return ( getUrlFromLangmasterPath ( server, pagePath, jcrLanguage) );

   else
  return ( getUrlFromPath ( server, pagePath, jcrLanguage) );

  }

   /**
  * CHL's code to generate publishExternalURL from given Host name and path of page with extra logging info specific to localized pages
  * @param server
   * @param path
   * @param jcrLanguage
   * @return
   */
   private String getUrlFromLangmasterPath(String server, String path, String jcrLanguage ) throws RepositoryException {

  String newPath = path;

  String url = "";

   if (StringUtils.contains(server, "helpx.qa.adobe.com")

  || StringUtils.contains(server, "helpx.stage.adobe.com")

  || StringUtils.contains(server, "learn.qa01.adobe.com")

  || StringUtils.contains(server, "helpx.adobe.com")) {

  newPath = StringUtils.replace(path, "/content/help/langmaster-replication/en/", "/", 1);

   //Check for pages such as /content/help/fr or /content/help/de
   if (StringUtils.equals(newPath, path)) {

  newPath = StringUtils.replace(path, "/content/help/langmaster-replication/", "/", 1);

   LOGGER.debug( "inside getUrlFromLangmasterPath(), path of page is : {}" , newPath );

  }

  }

   //Log an error if newPath is same as path
   if ( ! StringUtils.equals(newPath, path)) {

   /*
  * newPath should be /locale/product/page
  * Let's split into 3 strings : "" , locale , product/page
  */
   String pagePathUrl = newPath.split( "/" , 3)[1];

  String urlLocale = getUrlLocaleFromJcrLangueage ( jcrLanguage );

   if ( ! urlLocale.equals( pagePathUrl ) ) {

  newPath = StringUtils.replace(newPath, pagePathUrl, urlLocale, 1);

  }

  url = server + newPath;

   if (!StringUtils.endsWithIgnoreCase(url, ".html")) {

  url += ".html";

  }

  }

   else {

   LOGGER.error( "Unable to convert External Url from given path = {}" , newPath );

  }

   return url;

  }

   /**
  * CHL's code to generate publishExternalURL from given Host name and path of page with extra logging info specific to localized pages
  * @param server
   * @param path
   * @param jcrLanguage
   * @return
   */
   private String getUrlFromPath(String server, String path, String jcrLanguage ) throws RepositoryException {

  String newPath = path;

  String url = "";

   if (StringUtils.contains(server, "helpx.qa.adobe.com")

  || StringUtils.contains(server, "helpx.stage.adobe.com")

  || StringUtils.contains(server, "learn.qa01.adobe.com")

  || StringUtils.contains(server, "helpx.adobe.com")) {

  newPath = StringUtils.replace(path, "/content/help/en/", "/", 1);

   //Check for pages such as /content/help/fr or /content/help/de
   if (StringUtils.equals(newPath, path)) {

  newPath = StringUtils.replace(path, "/content/help/", "/", 1);

   LOGGER.debug( "inside getUrlFromPath(), path of page is : {}" , newPath );

  }

  }

   //Log an error if newPath is same as path
   if ( ! StringUtils.equals(newPath, path)) {

   /*
  * newPath should be /locale/product/page
  * Let's split into 3 strings : "" , locale , product/page
  */
   String pagePathUrl = newPath.split( "/" , 3)[1];

  String urlLocale = getUrlLocaleFromJcrLangueage ( jcrLanguage );

   if ( ! urlLocale.equals( pagePathUrl ) ) {

  newPath = StringUtils.replace(newPath, pagePathUrl, urlLocale, 1);

  }

  url = server + newPath;

   if (!StringUtils.endsWithIgnoreCase(url, ".html")) {

  url += ".html";

  }

  }

   else {

   LOGGER.error( "Unable to convert External Url from given path = {}" , newPath );

  }

   return url;

  }

   private String getUrlLocaleFromJcrLangueage ( String jcrLanguage ) throws PathNotFoundException, RepositoryException {

  String urlLocale = "";

  Session newSession = getRepositorySession ();

  Node localeMappingNode = newSession.getNode (Constants.LOCALE_MAPPING_PATH);

   if ( localeMappingNode.hasNode( jcrLanguage ) ) {

  urlLocale = localeMappingNode.getNode( jcrLanguage ).getProperty( Constants.LOCALE_MAPPING_URL_LOCALE_PROPERTY ).getString();

   LOGGER.debug( "URL Locale for jcr:language {} is {}" , jcrLanguage , urlLocale );

  }

   else {

   LOGGER.error( "Unable to get locale mapping for {}" , jcrLanguage );

  urlLocale = jcrLanguage;

  }

   return urlLocale;

  }

   /**
  * Give a page and session object. It updates all the relative references of the page
  * @param session
   * @param pageObject
   * @throws PathNotFoundException
  * @throws RepositoryException
  */
   @Override
   public void updateForwardPageReferences(Session session, String pageObject, boolean isOldProject) throws PathNotFoundException, RepositoryException {

  java.util.Set<String> exclude = new HashSet<String>();

  Node node = session.getNode(pageObject);

  Collection<String> adjusted;

   if(!pageObject.contains("/langmaster-replication/") || (pageObject.contains("/langmaster-replication/") && isOldProject))

  {

  adjusted = new ReferenceSearch().adjustReferences(node, "/content/help", "/content/help/langmaster-replication", false, exclude);

  }

   for(Map.Entry<String, String> entry: Constants.localeMap.entrySet())

  {

  adjusted = new ReferenceSearch().adjustReferences(node, "/content/help/langmaster-replication/" + entry.getValue(), "/content/help/langmaster-replication/" + entry.getKey(), false, exclude);

   if(adjusted!=null && adjusted.size()>0)

  {

   LOGGER.debug("Printing changed links for new site structre");

   for(String changedLinks: adjusted)

  {

   LOGGER.debug(changedLinks);

  }

  }

  }

  session.save();

  }

  

   @Override
   public void updateBackwardPageReferences(Session session, String pageObject) throws PathNotFoundException, RepositoryException {

  java.util.Set<String> exclude = new HashSet<String>();

  Node node = session.getNode(pageObject);

  Collection<String> adjusted;

   //change to older locale code scheme in legacy content
  
   for(Map.Entry<String, String> entry: Constants.localeMap.entrySet())

  {

  adjusted = new ReferenceSearch().adjustReferences(node, "/content/help/langmaster-replication/" + entry.getKey(), "/content/help/langmaster-replication/" + entry.getValue(), false, exclude);

   if(adjusted!=null && adjusted.size()>0)

  {

   LOGGER.debug("Printing changed links to new locale for asset " + pageObject + " are : " + Utils.toContentString(adjusted));

  }

  }

   //update references to that of older site structure
   adjusted = new ReferenceSearch().adjustReferences(node, "/content/help/langmaster-replication", "/content/help", false, exclude);

   LOGGER.debug("Printing changed links to legacy site structure for asset " + pageObject + " are : " + Utils.toContentString(adjusted));

  session.save();

  }

  

   /**
  * Give a page and session object. It updates all the relative references of the page
  * @param session
   * @param pageObject
   * @throws PathNotFoundException
  * @throws RepositoryException
  */
   @Override
   public void updatePageReferences(Session session, String pageObject, String sourceLang, String targetLang) throws PathNotFoundException, RepositoryException {

  java.util.Set<String> exclude = new HashSet<String>();

  Node node = session.getNode(pageObject);

  Collection<String> adjusted;

   //update references to that of older site structure
   adjusted = new ReferenceSearch().adjustReferences(node, "/content/help", "/content/help/langmaster-replication", false, exclude);

   LOGGER.debug("Printing changed links");

   for(String changedLinks: adjusted)

  {

   LOGGER.debug(changedLinks);

  }

  adjusted = new ReferenceSearch().adjustReferences(node, "/content/help/langmaster-replication/" + sourceLang + "/", "/content/help/langmaster-replication/" + targetLang + "/", false, exclude);

   for(String changedLinks: adjusted)

  {

   LOGGER.debug(changedLinks);

  }

  session.save();

  }

   /**
  * @param session
   * @param pageObject
   * @param search
   * @param replace
   * @throws PathNotFoundException
  * @throws RepositoryException
  */
   @Override
   public void updatePageReferencesForPreview(Session session, String pageObject, String search, String replace) throws PathNotFoundException, RepositoryException {

  java.util.Set<String> exclude = new HashSet<String>();

  Node node = session.getNode(pageObject);

  Collection<String> adjusted;

   //update references to that of older site structure
   adjusted = new ReferenceSearch().adjustReferences(node, search, replace, false, exclude);

   //printing changed links
   LOGGER.debug("Printing changed links");

   for(String changedLinks: adjusted)

  {

   LOGGER.debug(changedLinks);

  }

  session.save();

  }

   @Override
   public Boolean replicateUsingCustomAgent(Session jcrSession, ReplicationActionType replicationType, String pagePath, final String actualAgentName) throws RepositoryException, ReplicationException {

  ReplicationOptions replicationOptions = new ReplicationOptions();

   try {

  replicationOptions

  .setFilter(new com.day.cq.replication.AgentFilter() {

   @Override
   public boolean isIncluded(Agent agent) {

   // get names of agents for this publishing action
   String agentName = agent.getConfiguration()

  .getName();

   boolean includeAgent = false;

   if (actualAgentName.equals(agentName)) {

   LOGGER.debug("Enabling replication agent = "
   + agentName);

  includeAgent = agent.isEnabled();

  }

   return includeAgent;

  }

  });

   replicator.replicate(jcrSession, replicationType, pagePath,

  replicationOptions);

   LOGGER.debug("Replicating page: {}", pagePath);

   return true;

  } catch (ReplicationException e) {

  String message = e.getMessage();

   if (message.startsWith("Unable to create version")) {

   LOGGER.error(

   "Could not create a version of page when replicating it, but not sending an email message to the user",

  e);

  } else {

   LOGGER.debug(

   "Caught ReplicationException, but throwing it because it's not a failure to create a version: message = {}",

  message);

   throw e;

  }

  }

   return true;

  }

   @Override
   public WSLanguage getWSLangFromIsoLangCode(ResourceResolver resolver,

  String IsoLangCode) throws Exception {

  WSLanguage wsLang = wsLangService.getWSLanguageFromIsoLanguageCode(resolver, IsoLangCode);

   return wsLang;

  }

   @Override
   public ArrayList<String> getCountrySites(String page) throws PathNotFoundException, RepositoryException

  {

  

  ArrayList<String> countrySites = new ArrayList<String>();

  String locale = Utils.getFolderLocaleFromPage(page);

  Session session = getRepositorySession();

  Node helpxLMNode = session.getNode(Constants.HELPX_LOCALE_MAPPING_PATH);

  NodeIterator ni = helpxLMNode.getNodes();

  String folderLocale;

   while(ni.hasNext())

  {

  Node localeNode = ni.nextNode();

   if(localeNode.hasProperty("folderLocale"))

  {

  folderLocale = localeNode.getProperty("folderLocale").getString();

   if(folderLocale.endsWith("/"+locale))

  {

   LOGGER.debug("Adding country sites to the list : " + localeNode.getPath());

  countrySites.add(localeNode.getPath());

  }

  }

  }

   return countrySites; 

  }

  

   /**
  * This function creates the entry of the new HandOff workflow metadata in /var/workflowx/metadata
  * @param workItem
   * @param wfSession
   * @return
   * @throws RepositoryException
  * @throws Exception
  */
  //TODO Can optimize this code more.
   @Override
   public Node createWorkflowMetaDataStructure(WorkItem workItem, com.adobe.granite.workflow.WorkflowSession wfSession) throws RepositoryException,Exception {

  String workflowId = workItem.getWorkflow().getId();

  Session session = getRepositorySession();

   try {

  Node workflowNode = session.getNode(workflowId);

  String wfDataPath = anuvaadConfigurationService.getWorkflowDataBasePath();

  Node xliffdir = null;

   // Placing the creation of workflow node in /var/workflowx/metadata
  // in synchronized block as multiple
  // threads can modify the same nodes in repository here.
  //This code is per handoff only HandOffs done simultaneously will wait
   Node workFlowDataNode = null;

   synchronized (this) {

   if (!session.nodeExists(wfDataPath)) {

  Node metadataFolder = JcrUtil.createPath(wfDataPath, SLING_FOLDER, session);

  metadataFolder.addMixin(MIX_LOCKABLE);

  metadataFolder.addMixin(MIX_ACCESS_CONTROLLABLE);

  session.save();

  }

  Node metaDataNode = session.getNode(wfDataPath);

  String workFlowDataNodePath = getWorkflowDataPath(workflowId);

  Node dateNode = workflowNode.getParent();

  Node workflowDataParent = null;

   // Creating the date folder in workflow date location
   if (!metaDataNode.hasNode(dateNode.getName())) {

  workflowDataParent = metaDataNode.addNode(dateNode.getName(), SLING_FOLDER);

  workflowDataParent.getSession().save();

  } else {

  workflowDataParent = session.getNode(wfDataPath + "/" + dateNode.getName());

  }

   // creating has nt:unstructered node with model id
   if (!workflowDataParent.hasNode(workflowNode.getName())) {

  workFlowDataNode = workflowDataParent.addNode(workflowNode.getName(), NT_UNSTRUCTURED);

  workFlowDataNode.setProperty("dateCreated",

  StringUtils.substringBefore(workflowDataParent.getName(), "_"));

  workFlowDataNode.getSession().save();

  } else {

  workFlowDataNode = workflowDataParent.getNode(workflowNode.getName());

  }

  }

   // Create a node for the nt:file
   if (workFlowDataNode.hasNode(Constants.NODENAME_MASTER_XLIFF_NODE)) {

  xliffdir = workFlowDataNode.getNode(Constants.NODENAME_MASTER_XLIFF_NODE);

  } else {

  xliffdir = workFlowDataNode.addNode(Constants.NODENAME_MASTER_XLIFF_NODE, NT_FOLDER);

  xliffdir.addMixin("mix:lockable");

  }

   // Create a import folder
   Node importDir = null;

   if (!xliffdir.hasNode(Constants.NODENAME_MASTER_IMPORT_NODE)) {

  importDir = xliffdir.addNode(Constants.NODENAME_MASTER_IMPORT_NODE, NT_FOLDER);

  importDir.addMixin("mix:lockable");

  }

  workFlowDataNode.getSession().save();

   return xliffdir;

  } catch (RepositoryException e) {

   LOGGER.error("Error in creating workflowMetaData structure for workflow"+workflowId);

   LOGGER.error(Utils.getStackTraceAsString(e));

   throw e;

  }

  }

  

   /**
  * To generate the XLiff Blob Meta Data. This function creates the workflow
  * node in /var/workflowx/metadata(configurable in osgi) and creates the
  * english xliff files inside it. This location is used by gms system to
  * fetch the english xliff files.
  *
  * @param outputstream
   * out stream
  * @param name
   * page name -> xliff name. This is the path of the assetNode.
  * This is converted to xliff name using Base64 encoding.
  * @param workflowSession
   * workflow session
  */
   @Override
   public String generateXliffBlobInMetatData(ByteArrayOutputStream outputstream, String name,Node xliffDir,

  com.adobe.granite.workflow.WorkflowSession workflowSession, String okapiWF) throws RepositoryException {

  String nameStr = null;

   try {

  Session session = workflowSession.adaptTo(Session.class);

  String wfDataPath = anuvaadConfigurationService.getWorkflowDataBasePath();

  

  nameStr = new String(Base64.encodeBase64(name.getBytes())) + "."
   + okapiWF;

   if(!xliffDir.hasNode(nameStr)){

  Node xlifffile = xliffDir.addNode(nameStr, NT_FILE);

   // Create a node for the nt:resource
   Node jcrContent = xlifffile.addNode(JCR_CONTENT, NT_RESOURCE);

   // Get a ValueFactory for creating the Binary type
   ValueFactory vf = session.getValueFactory();

   // Pump the response stream into the jcr:data property
   jcrContent.setProperty(JCR_DATA, vf.createBinary(new ByteArrayInputStream(outputstream.toByteArray())));

   // Save the session
   xlifffile.getSession().save();

  }

  } catch (RepositoryException e) {

   LOGGER.error("Anuvaad :Error occured: ", Utils.getStackTraceAsString(e));

   throw e;

  }

   LOGGER.debug("Anuvaad :Exit generateXliffBlobInMetatData()");

   return nameStr;

  }

   @Override
   public Set<String> getReferencedPagesToReplicate(Node jobNode, String gmsTargetLang) throws ValueFormatException, PathNotFoundException, RepositoryException {

  NodeIterator iterator = jobNode.getNodes();

  Set<String> pages = new HashSet<String>();

   while (iterator.hasNext()) {

  Node assetNode = iterator.nextNode();

   if (assetNode.getName().equals("jcr:content"))

   continue;

  NodeIterator langNodeItr = assetNode.getNodes();

  

   boolean foundLocaleNode = false;

   while (langNodeItr.hasNext()) {

  Node langNode = langNodeItr.nextNode();

   if(langNode.getName().equals(gmsTargetLang) && (langNode.getProperty(Constants.ASSET_LOCALE_STATUS).getLong()==AssetLocaleStatus.PUBLISH_SUBMIT.getAssetStatusCode() || langNode.getProperty(Constants.ASSET_LOCALE_STATUS).getLong()==AssetLocaleStatus.CANCELLED.getAssetStatusCode()))

  {

   //asset imported in provided locale
   Value[] publishedPages = null;

   if(langNode.hasProperty(Constants.PUBLISHED_PAGES))

  {

  publishedPages = langNode.getProperty(Constants.PUBLISHED_PAGES).getValues();

  }

   else
   {

   LOGGER.info("Language node "+langNode.getPath()+ " doesnt have publishedPages property ");

  }

   LOGGER.info("Printing published pages");

   for(Value value: publishedPages)

  {

   LOGGER.info(value.getString());

  pages.add(value.getString());

  }

  foundLocaleNode = true;

   break;

  }

   else
   {

   LOGGER.info("language doesn't match");

  }

  }

   if(!foundLocaleNode)

  {

   //asset node does not have locale node. One of the asset is yet to be completed from GMS
   LOGGER.info("resource node "+ assetNode.getPath()+" doesn't have language node");

   return null;

  } 

  }

   return pages;

  }

   /**
  * {@inheritDoc}
  */
   @Override
   public String getProdLangMappingRoot()

  {

   if(anuvaadConfigurationService.getProdLangMappingFlag())

  {

   return PRODUCT_LANGUAGE_MAPIING_ROOT;

  }

   else
   {

   return PRODUCT_LANGUAGE_MAPIING_ROOT_LEGACY;

  }

  }

   @Override
   public ResourceResolver getResourceResolverFromSession(

  Session sessionToUse) {

   try {

   return  resolverFactory.getServiceResourceResolver(null);

  } catch (Exception e) {

   LOGGER.error("Cannot get ResourceResolver: ", e);

   return null;

  }

}

  

  

}

1 Accepted Solution

Avatar

Correct answer by
Level 10

As Scott mentioned, you would need to modify the source code to bring it up. At bare minimum, fix the following:

Admin session would not work - return repository.loginAdministrative(null);

Use correct jar versions  - When you build the project using Maven Archetype 13 (or higher), you would get the required dependencies and correct jar versions

View solution in original post

4 Replies

Avatar

Level 10

There are some issues here:

1. Its better practice to use R6 annotations as opposed to SRC annotations.

2- To get a session, you should use a System User and map that using Mapping Service. For details - see Adobe Experience Manager Help | Querying Adobe Experience Manager 6.4 JCR data using the QueryBuilde...

For AEM 6.4 - you should be using a Maven Archetype 13 (or higher) and use UBER 6.4 jar. See the article I referenced.

After you perform these tasks - your bundle will go into Active State.

Avatar

Level 10

In addition - as your example uses QueryBuilder API, see our HELPX article that shows how to successfully use this API to query the AEM JCR:

Adobe Experience Manager Help | Querying Adobe Experience Manager 6.4 JCR data using the QueryBuilde... 

Avatar

Level 2

Hi, thanks for the inputs.

Some of the components having SRC annotation are in active state.

Is there any way I can install my bundle that used to work on AEM 6.3 versions without any change as there are several servlets and it will take a lot to rework to incorporate the changes you suggested.

Avatar

Correct answer by
Level 10

As Scott mentioned, you would need to modify the source code to bring it up. At bare minimum, fix the following:

Admin session would not work - return repository.loginAdministrative(null);

Use correct jar versions  - When you build the project using Maven Archetype 13 (or higher), you would get the required dependencies and correct jar versions