/**
   * This method removes a Language from the system and also cleans out all depending
   * repositoryLanguages.
   */
  public void delete(Database db, LanguageVO languageVO)
      throws ConstraintException, SystemException {
    Language language = getLanguageWithId(languageVO.getId(), db);
    RepositoryLanguageController.getController()
        .deleteAllRepositoryLanguageWithLanguage(language, db);

    deleteEntity(LanguageImpl.class, languageVO.getLanguageId(), db);
  }
  public void removeSiteNodeReferences(
      Map<SiteNodeVO, RegistryVO> siteNodeRegistryPair,
      InfoGluePrincipal infoGluePrincipal,
      Database db)
      throws SystemException, Exception {
    SiteNodeVO siteNodeVO;
    RegistryVO registryVO;
    for (Map.Entry<SiteNodeVO, RegistryVO> pair : siteNodeRegistryPair.entrySet()) {
      siteNodeVO = pair.getKey();
      registryVO = pair.getValue();
      if (logger.isDebugEnabled()) {
        logger.debug(
            "About to clean SiteNode "
                + siteNodeVO.getContentVersionId()
                + " for references to: "
                + registryVO.getEntityName()
                + "<"
                + registryVO.getEntityId()
                + ">");
      }
      try {
        Integer metaInfoContentId = siteNodeVO.getMetaInfoContentId();
        LanguageVO masterLanguageVO =
            LanguageController.getController().getMasterLanguage(siteNodeVO.getRepositoryId(), db);
        String pageStructure =
            ContentController.getContentController()
                .getContentAttribute(
                    db, metaInfoContentId, masterLanguageVO.getId(), "ComponentStructure");

        if (registryVO.getReferenceType().equals(RegistryVO.PAGE_COMPONENT))
          pageStructure =
              deleteComponentFromXML(pageStructure, new Integer(registryVO.getEntityId()));
        if (registryVO.getReferenceType().equals(RegistryVO.PAGE_COMPONENT_BINDING))
          pageStructure =
              deleteComponentBindingFromXML(
                  pageStructure, new Integer(registryVO.getEntityId()), registryVO.getEntityName());

        ContentVersionVO contentVersionVO =
            ContentVersionController.getContentVersionController()
                .getLatestActiveContentVersionVO(metaInfoContentId, masterLanguageVO.getId(), db);
        ContentVersionController.getContentVersionController()
            .updateAttributeValue(
                contentVersionVO.getContentVersionId(),
                "ComponentStructure",
                pageStructure,
                infoGluePrincipal,
                db);
      } catch (Exception e) {
        logger.warn(
            "Could not remove reference on "
                + (siteNodeVO == null ? "null" : siteNodeVO.getName())
                + ": "
                + e.getMessage(),
            e);
      }
    }
  }
  private void addSiteNodeInconsistency(List inconsistencies, RegistryVO registryVO, Database db)
      throws Exception {
    try {
      String referencingEntityName = registryVO.getReferencingEntityName();
      String referencingEntityCompletingName = registryVO.getReferencingEntityCompletingName();
      Integer referencingEntityId = new Integer(registryVO.getReferencingEntityId());
      Integer referencingEntityCompletingId =
          new Integer(registryVO.getReferencingEntityCompletingId());

      if (referencingEntityCompletingName.equals(SiteNode.class.getName())) {
        SiteNodeVO siteNodeVO =
            SiteNodeController.getController()
                .getSiteNodeVOWithId(
                    new Integer(registryVO.getReferencingEntityCompletingId()), db);
        if (siteNodeVO != null) {
          LanguageVO masterLanguageVO =
              LanguageController.getController().getMasterLanguage(siteNodeVO.getRepositoryId());
          SiteNodeVersionVO siteNodeVersionVO =
              SiteNodeVersionController.getController()
                  .getLatestActiveSiteNodeVersionVO(db, siteNodeVO.getId());

          if (siteNodeVersionVO != null
              && siteNodeVersionVO.getId().intValue() == referencingEntityId.intValue())
            inconsistencies.add(registryVO);
        }
      } else if (referencingEntityCompletingName.equals(Content.class.getName())) {
        ContentVO contentVO =
            ContentController.getContentController()
                .getContentVOWithId(new Integer(registryVO.getReferencingEntityCompletingId()), db);
        if (contentVO != null) {
          LanguageVO masterLanguageVO =
              LanguageController.getController().getMasterLanguage(contentVO.getRepositoryId());
          ContentVersionVO contentVersionVO =
              ContentVersionController.getContentVersionController()
                  .getLatestActiveContentVersionVO(contentVO.getId(), masterLanguageVO.getId(), db);

          if (contentVersionVO != null
              && contentVersionVO.getId().intValue() == referencingEntityId.intValue())
            inconsistencies.add(registryVO);
        }
      } else {
        logger.error(
            "The registry contained a not supported referencingEntityCompletingName:"
                + referencingEntityCompletingName);
      }
    } catch (Exception e) {
      logger.error(
          "There seems to be a problem with finding the inconsistency for registryVO "
              + registryVO.getRegistryId()
              + ":"
              + e.getMessage());
    }
  }
  public LanguageVO update(LanguageVO languageVO) throws ConstraintException, SystemException {
    Database db = CastorDatabaseService.getDatabase();
    ConstraintExceptionBuffer ceb = new ConstraintExceptionBuffer();

    Language language = null;

    beginTransaction(db);

    try {
      // add validation here if needed
      language = getLanguageWithId(languageVO.getLanguageId(), db);
      language.setValueObject(languageVO);

      // If any of the validations or setMethods reported an error, we throw them up now before
      // create.
      ceb.throwIfNotEmpty();

      commitTransaction(db);
    } catch (ConstraintException ce) {
      logger.warn("An error occurred so we should not complete the transaction:" + ce, ce);
      rollbackTransaction(db);
      throw ce;
    } catch (Exception e) {
      logger.error("An error occurred so we should not complete the transaction:" + e, e);
      rollbackTransaction(db);
      throw new SystemException(e.getMessage());
    }

    return language.getValueObject();
  }
  /** This method returns language with the languageCode sent in. */
  public Locale getLocaleWithId(Integer languageId) {
    Locale locale = Locale.getDefault();

    if (languageId != null) {
      try {
        LanguageVO languageVO = getLanguageVOWithId(languageId);
        locale = new Locale(languageVO.getLanguageCode());
      } catch (Exception e) {
        logger.error(
            "An error occurred in getLocaleWithId: getting locale with languageid:"
                + languageId
                + ","
                + e,
            e);
      }
    }

    return locale;
  }
  /**
   * This method returns the master language. todo - add attribute on repositoryLanguage to be able
   * to sort them... and then fetch the first
   */
  public LanguageVO getMasterLanguage(Integer repositoryId, Database db)
      throws SystemException, Exception {
    LanguageVO languageVO = null;

    String languageKey = "" + repositoryId;
    logger.info("languageKey:" + languageKey);
    languageVO = (LanguageVO) CacheController.getCachedObject("masterLanguageCache", languageKey);
    if (languageVO != null) {
      logger.info("There was an cached master language:" + languageVO.getName());
    } else {
      Language language = getMasterLanguage(db, repositoryId);

      if (language != null) {
        languageVO = language.getValueObject();
        CacheController.cacheObject("masterLanguageCache", languageKey, languageVO);
      }
    }

    return languageVO;
  }
  /**
   * This method returns the master language. todo - add attribute on repositoryLanguage to be able
   * to sort them... and then fetch the first
   */
  public LanguageVO getMasterLanguage(Integer repositoryId) throws SystemException, Exception {
    LanguageVO languageVO = null;

    String languageKey = "" + repositoryId;
    logger.info("languageKey:" + languageKey);
    languageVO = (LanguageVO) CacheController.getCachedObject("masterLanguageCache", languageKey);
    if (languageVO != null) {
      logger.info("There was an cached master language:" + languageVO.getName());
    } else {
      Database db = CastorDatabaseService.getDatabase();
      ConstraintExceptionBuffer ceb = new ConstraintExceptionBuffer();

      Language language = null;

      beginTransaction(db);

      try {
        language = getMasterLanguage(db, repositoryId);

        // If any of the validations or setMethods reported an error, we throw them up now before
        // create.
        ceb.throwIfNotEmpty();

        if (language != null) {
          languageVO = language.getValueObject();
          CacheController.cacheObject("masterLanguageCache", languageKey, languageVO);
        }

        commitTransaction(db);
      } catch (Exception e) {
        logger.error("An error occurred so we should not complete the transaction:" + e, e);
        rollbackTransaction(db);
        throw new SystemException(e.getMessage());
      }
    }

    return languageVO;
  }
  /**
   * This method simulates a call to a page so all castor caches fills up before we throw the old
   * page cache.
   *
   * @param db
   * @param siteNodeId
   * @param languageId
   * @param contentId
   */
  public void recache(DatabaseWrapper dbWrapper, Integer siteNodeId)
      throws SystemException, Exception {
    logger.info("recache starting..");

    HttpHelper helper = new HttpHelper();
    String recacheUrl =
        CmsPropertyHandler.getRecacheUrl()
            + "?siteNodeId="
            + siteNodeId
            + "&refresh=true&isRecacheCall=true";
    String response = helper.getUrlContent(recacheUrl, 30000);

    String recacheBaseUrl = CmsPropertyHandler.getRecacheUrl().replaceAll("/ViewPage.action", "");
    String pathsToRecacheOnPublishing = CmsPropertyHandler.getPathsToRecacheOnPublishing();
    if (pathsToRecacheOnPublishing.indexOf("pathsToRecacheOnPublishing") == -1) {
      String[] pathsToRecacheOnPublishingArray = pathsToRecacheOnPublishing.split(",");
      for (int i = 0; i < pathsToRecacheOnPublishingArray.length; i++) {
        recacheUrl =
            recacheBaseUrl
                + pathsToRecacheOnPublishingArray[i]
                + "?refresh=true&isRecacheCall=true";
        logger.info("calling recacheUrl:" + recacheUrl);
      }
    }

    LanguageVO masterLanguageVO =
        LanguageDeliveryController.getLanguageDeliveryController()
            .getMasterLanguageForSiteNode(dbWrapper.getDatabase(), siteNodeId);
    if (masterLanguageVO == null)
      throw new SystemException("There was no master language for the siteNode " + siteNodeId);

    Integer languageId = masterLanguageVO.getLanguageId();
    if (languageId == null) languageId = masterLanguageVO.getLanguageId();

    Integer contentId = new Integer(-1);

    Principal principal = (Principal) CacheController.getCachedObject("userCache", "anonymous");
    if (principal == null) {
      Map arguments = new HashMap();
      arguments.put("j_username", CmsPropertyHandler.getAnonymousUser());
      arguments.put("j_password", CmsPropertyHandler.getAnonymousPassword());

      principal =
          ExtranetController.getController()
              .getAuthenticatedPrincipal(dbWrapper.getDatabase(), arguments);

      if (principal != null) CacheController.cacheObject("userCache", "anonymous", principal);
    }

    FakeHttpSession fakeHttpServletSession = new FakeHttpSession();
    FakeHttpServletResponse fakeHttpServletResponse = new FakeHttpServletResponse();
    FakeHttpServletRequest fakeHttpServletRequest = new FakeHttpServletRequest();
    fakeHttpServletRequest.setParameter("siteNodeId", "" + siteNodeId);
    fakeHttpServletRequest.setParameter("languageId", "" + languageId);
    fakeHttpServletRequest.setParameter("contentId", "" + contentId);
    fakeHttpServletRequest.setRequestURI("ViewPage.action");

    fakeHttpServletRequest.setAttribute("siteNodeId", "" + siteNodeId);
    fakeHttpServletRequest.setAttribute("languageId", "" + languageId);
    fakeHttpServletRequest.setAttribute("contentId", "" + contentId);

    fakeHttpServletRequest.setServletContext(DeliverContextListener.getServletContext());

    BrowserBean browserBean = new BrowserBean();
    // this.browserBean.setRequest(getRequest());

    NodeDeliveryController nodeDeliveryController =
        NodeDeliveryController.getNodeDeliveryController(siteNodeId, languageId, contentId);
    IntegrationDeliveryController integrationDeliveryController =
        IntegrationDeliveryController.getIntegrationDeliveryController(
            siteNodeId, languageId, contentId);
    TemplateController templateController =
        getTemplateController(
            dbWrapper,
            siteNodeId,
            languageId,
            contentId,
            new FakeHttpServletRequest(),
            (InfoGluePrincipal) principal,
            false,
            browserBean,
            nodeDeliveryController,
            integrationDeliveryController);

    DeliveryContext deliveryContext =
        DeliveryContext.getDeliveryContext(/*(InfoGluePrincipal)this.principal*/ );
    // deliveryContext.setRepositoryName(repositoryName);
    deliveryContext.setSiteNodeId(siteNodeId);
    deliveryContext.setContentId(contentId);
    deliveryContext.setLanguageId(languageId);
    deliveryContext.setPageKey("" + System.currentTimeMillis());
    // deliveryContext.setSession(new Session(fakeHttpServletSession));
    // deliveryContext.setInfoGlueAbstractAction(null);
    deliveryContext.setHttpServletRequest(fakeHttpServletRequest);
    deliveryContext.setHttpServletResponse(fakeHttpServletResponse);

    templateController.setDeliveryContext(deliveryContext);

    // We don't want a page cache entry to be created
    deliveryContext.setDisablePageCache(true);

    SiteNodeVO siteNodeVO = templateController.getSiteNode(siteNodeId);
    SiteNodeVO rootSiteNodeVO =
        templateController.getRepositoryRootSiteNode(siteNodeVO.getRepositoryId());

    recurseSiteNodeTree(
        rootSiteNodeVO.getId(), languageId, templateController, principal /*, dbWrapper*/, 1, 0);

    List templates =
        ContentController.getContentController()
            .getContentVOWithContentTypeDefinition("HTMLTemplate", dbWrapper.getDatabase());
    Iterator templatesIterator = templates.iterator();
    {
      ContentVO template = (ContentVO) templatesIterator.next();

      String templateString =
          templateController.getContentAttribute(template.getId(), languageId, "Template", true);
    }

    RepositoryVO repository =
        RepositoryDeliveryController.getRepositoryDeliveryController()
            .getMasterRepository(dbWrapper.getDatabase());

    RepositoryDeliveryController.getRepositoryDeliveryController()
        .getRepositoryVOListFromServerName(
            dbWrapper.getDatabase(), "localhost", "8080", repository.getName());

    logger.info("recache stopped..");
  }
  /**
   * @deprecated This method handles clean up of ContentVersions poorly. Please refer to {@link
   *     #removeContentReferences(Map, InfoGluePrincipal, Database)} and {@link
   *     #removeSiteNodeReferences(Map, InfoGluePrincipal, Database)} instead.
   */
  public void removeReferences(Integer registryId, InfoGluePrincipal infoGluePrincipal, Database db)
      throws SystemException, Exception {
    RegistryVO registryVO = RegistryController.getController().getRegistryVOWithId(registryId, db);
    String referencingEntityName = registryVO.getReferencingEntityName();
    String referencingEntityCompletingName = registryVO.getReferencingEntityCompletingName();
    Integer referencingEntityId = new Integer(registryVO.getReferencingEntityId());

    if (referencingEntityCompletingName.equals(SiteNode.class.getName())) {
      SiteNodeVO siteNodeVO =
          SiteNodeController.getController()
              .getSiteNodeVOWithId(new Integer(registryVO.getReferencingEntityCompletingId()), db);
      if (siteNodeVO != null) {
        Integer metaInfoContentId = siteNodeVO.getMetaInfoContentId();
        LanguageVO masterLanguageVO =
            LanguageController.getController().getMasterLanguage(siteNodeVO.getRepositoryId(), db);
        String pageStructure =
            ContentController.getContentController()
                .getContentAttribute(
                    db, metaInfoContentId, masterLanguageVO.getId(), "ComponentStructure");

        if (registryVO.getReferenceType().equals(RegistryVO.PAGE_COMPONENT))
          pageStructure =
              deleteComponentFromXML(pageStructure, new Integer(registryVO.getEntityId()));
        if (registryVO.getReferenceType().equals(RegistryVO.PAGE_COMPONENT_BINDING))
          pageStructure =
              deleteComponentBindingFromXML(
                  pageStructure, new Integer(registryVO.getEntityId()), registryVO.getEntityName());

        ContentVersionVO contentVersionVO =
            ContentVersionController.getContentVersionController()
                .getLatestActiveContentVersionVO(metaInfoContentId, masterLanguageVO.getId(), db);
        ContentVersionController.getContentVersionController()
            .updateAttributeValue(
                contentVersionVO.getContentVersionId(),
                "ComponentStructure",
                pageStructure,
                infoGluePrincipal,
                db);
      }
    } else if (referencingEntityCompletingName.equals(Content.class.getName())) {
      if (referencingEntityName.equals(ContentVersion.class.getName())) {
        ContentVersionVO contentVersionVO =
            ContentVersionController.getContentVersionController()
                .getContentVersionVOWithId(referencingEntityId, db);
        if (contentVersionVO != null) {
          String versionValue = contentVersionVO.getVersionValue();

          if (registryVO.getReferenceType().equals(RegistryVO.INLINE_LINK))
            versionValue =
                deleteInlineLinks(versionValue, new Integer(registryVO.getEntityId()), db);
          if (registryVO.getReferenceType().equals(RegistryVO.INLINE_ASSET))
            versionValue = deleteInlineAssets(versionValue, new Integer(registryVO.getEntityId()));
          if (registryVO.getReferenceType().equals(RegistryVO.INLINE_SITE_NODE_RELATION))
            versionValue =
                deleteInlineSiteNodeRelations(versionValue, new Integer(registryVO.getEntityId()));
          if (registryVO.getReferenceType().equals(RegistryVO.INLINE_CONTENT_RELATION))
            versionValue =
                deleteInlineContentRelations(versionValue, new Integer(registryVO.getEntityId()));

          contentVersionVO.setVersionModifier(infoGluePrincipal.getName());
          contentVersionVO.setModifiedDateTime(DateHelper.getSecondPreciseDate());
          contentVersionVO.setVersionValue(versionValue);

          ContentVersionController.getContentVersionController()
              .update(
                  contentVersionVO.getContentVersionId(), contentVersionVO, infoGluePrincipal, db);
        }
      }
    } else {
      logger.error(
          "The registry contained a not supported referencingEntityCompletingName:"
              + referencingEntityCompletingName);
    }
  }