com.idega.block.article.bean.ArticleItemBean.java Source code

Java tutorial

Introduction

Here is the source code for com.idega.block.article.bean.ArticleItemBean.java

Source

/*
 * $Id: ArticleItemBean.java,v 1.88 2009/01/10 12:24:10 valdas Exp $
 *
 * Copyright (C) 2004-2005 Idega. All Rights Reserved.
 *
 * This software is the proprietary information of Idega.
 * Use is subject to license terms.
 *
 */
package com.idega.block.article.bean;

import java.io.IOException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.httpclient.HttpException;
import org.apache.webdav.lib.PropertyName;
import org.apache.webdav.lib.WebdavResources;

import com.idega.block.article.ArticleCacher;
import com.idega.block.article.business.ArticleConstants;
import com.idega.block.article.business.ArticleUtil;
import com.idega.block.article.data.ArticleEntity;
import com.idega.block.article.data.dao.ArticleDao;
import com.idega.block.article.data.dao.CategoryDao;
import com.idega.business.IBOLookup;
import com.idega.content.bean.ContentItem;
import com.idega.content.bean.ContentItemBean;
import com.idega.content.bean.ContentItemCase;
import com.idega.content.business.ContentConstants;
import com.idega.content.business.ContentUtil;
import com.idega.core.accesscontrol.business.AccessController;
import com.idega.core.builder.business.BuilderService;
import com.idega.core.builder.business.BuilderServiceFactory;
import com.idega.core.content.RepositoryHelper;
import com.idega.data.IDOStoreException;
import com.idega.idegaweb.IWMainApplication;
import com.idega.idegaweb.IWMainApplicationSettings;
import com.idega.idegaweb.IWUserContext;
import com.idega.idegaweb.UnavailableIWContext;
import com.idega.presentation.IWContext;
import com.idega.slide.business.IWSlideSession;
import com.idega.slide.util.WebdavExtendedResource;
import com.idega.slide.util.WebdavRootResource;
import com.idega.user.business.UserBusiness;
import com.idega.user.data.Group;
import com.idega.user.data.User;
import com.idega.util.CoreConstants;
import com.idega.util.CoreUtil;
import com.idega.util.ListUtil;
import com.idega.util.StringHandler;
import com.idega.util.StringUtil;
import com.idega.util.expression.ELUtil;
import com.idega.xml.XMLException;

/**
 * <p>
 * This is a JSF managed bean that manages each article instance and delegates
 * all calls to the correct localized instance. You can find article edition forms at http://localhost:8080/workspace/content/article/
 * <p>
 * Last modified: $Date: 2009/01/10 12:24:10 $ by $Author: valdas $
 *
 * @author Anders Lindman,<a href="mailto:tryggvi@idega.com">Tryggvi Larusson</a>
 * @version $Revision: 1.88 $
 */
public class ArticleItemBean extends ContentItemBean implements Serializable, ContentItem, ValueChangeListener {

    private static final long serialVersionUID = 4514851565086272678L;

    private static final Logger LOGGER = Logger.getLogger(ArticleItemBean.class.getName());

    private final static String ARTICLE_FILE_SUFFIX = ".xml";

    public final static String TYPE_PREFIX = "IW:";
    public final static String CONTENT_TYPE = "ContentType";
    public final static String CONTENT_TYPE_WITH_PREFIX = TYPE_PREFIX + CONTENT_TYPE;

    public static final PropertyName PROPERTY_CONTENT_TYPE = new PropertyName(TYPE_PREFIX, CONTENT_TYPE);

    private ArticleLocalizedItemBean localizedArticle;
    private String baseFolderLocation;
    private String languageChange;
    private boolean allowFallbackToSystemLanguage = false;
    private String resourcePath;
    private boolean availableInRequestedLanguage = false;

    private boolean partOfArticleList = false;

    //Request scope so this should work well and fast
    private Boolean allowedToEditByCurrentUser = null;

    private CategoryDao getCategoryDao() {
        return ELUtil.getInstance().getBean(CategoryDao.BEAN_NAME);
    }

    public ArticleItemBean() {
        super();
    }

    private ArticleDao getArticleDAO() {
        ArticleDao articleDAO = ELUtil.getInstance().getBean(ArticleDao.BEAN_NAME);
        return articleDAO;
    }

    public Boolean isAllowedToEditByCurrentUser() {
        if (allowedToEditByCurrentUser != null) {
            return allowedToEditByCurrentUser;
        }

        //This is expensive operation, it is better to have called isAllowedToEditByCurrentUser(iwc) first

        IWContext iwc = CoreUtil.getIWContext();
        return isAllowedToEditByCurrentUser(iwc);

    }

    /**
     * Sets if this article is allowed to be edited for the current user, this property is
     * saved for this instance and later is returned by isAllowedToEditByCurrentUser.
     *
     * @param currentUser the current user for which the check will be done
     * @return True if it is allowed to edit, false otherwise.
     */
    public Boolean isAllowedToEditByCurrentUser(IWContext iwc) {
        IWMainApplicationSettings settings = iwc.getIWMainApplication().getSettings();
        if (!settings.getBoolean(ArticleConstants.USE_ROLES_IN_ARTICLE, Boolean.FALSE)) {
            allowedToEditByCurrentUser = Boolean.TRUE;
            return allowedToEditByCurrentUser;
        }

        if (allowedToEditByCurrentUser != null)
            return allowedToEditByCurrentUser;
        if (!iwc.isLoggedOn()) {
            allowedToEditByCurrentUser = Boolean.FALSE;
            return allowedToEditByCurrentUser;
        }

        AccessController accessController = iwc.getAccessController();
        try {
            if (accessController.isAdmin(iwc)) {
                allowedToEditByCurrentUser = Boolean.TRUE;
                return allowedToEditByCurrentUser;
            }
        } catch (Exception e) {
            LOGGER.log(Level.WARNING, "Failed to check is admin", e);
            return Boolean.FALSE;
        }

        User currentUser = iwc.getCurrentUser();
        ArticleEntity articleEntity = getArticleEntity(false);
        if (articleEntity == null) {
            //By default there was permitted to edit any article by any user
            allowedToEditByCurrentUser = Boolean.TRUE;
            return allowedToEditByCurrentUser;
        }

        Set<Integer> editors = articleEntity.getEditors();
        if (ListUtil.isEmpty(editors)) {
            //By default there was permitted to edit any article by any user
            allowedToEditByCurrentUser = Boolean.TRUE;
            return allowedToEditByCurrentUser;
        }

        Collection<Group> parentGroups;
        try {
            UserBusiness userBusiness = IBOLookup.getServiceInstance(iwc, UserBusiness.class);
            parentGroups = userBusiness.getUserGroups(currentUser);

            //TODO: this probably never happens
            if (ListUtil.isEmpty(parentGroups)) {
                allowedToEditByCurrentUser = Boolean.FALSE;
                return allowedToEditByCurrentUser;
            }

        } catch (Exception e) {
            LOGGER.log(Level.WARNING, "Failed getting is allowed to edit by current user " + currentUser.getId()
                    + " article " + getResourcePath(), e);
            return Boolean.FALSE;
        }
        allowedToEditByCurrentUser = Boolean.FALSE;
        for (Group group : parentGroups) {
            if (editors.contains(group.getPrimaryKey())) {
                allowedToEditByCurrentUser = Boolean.TRUE;
                break;
            }
        }
        return allowedToEditByCurrentUser;
    }

    public void setAllowedToEditByGroup(Group group) {
        List<Integer> groupsIds = Arrays.asList(Integer.valueOf(group.getId()));
        setAllowedToEditByGroupsIds(groupsIds);
    }

    public void setAllowedToEditByGroups(Collection<Group> groups) {
        Collection<Integer> groupsIds = new HashSet<Integer>(groups.size());
        for (Group group : groups) {
            groupsIds.add(Integer.valueOf(group.getId()));
        }
        setAllowedToEditByGroupsIds(groupsIds);
    }

    public void setAllowedToEditByGroupsIds(Collection<Integer> groupsIds) {
        if (ListUtil.isEmpty(groupsIds)) {
            return;
        }
        allowedToEditByCurrentUser = null;
        ArticleEntity articleEntity = getArticleEntity(false);
        if (articleEntity != null) {
            if (groupsIds instanceof Set) {
                articleEntity.setEditors((Set<Integer>) groupsIds);
            } else {
                articleEntity.setEditors(new HashSet<Integer>(groupsIds));
            }
        }
    }

    /**
     *
     * <p>Checks for existing {@link ArticleEntity}, creates new if
     * not found in database.</p>
     * @param createIfNotFound - <code>true</code> if new entity is required,
     * when no {@link ArticleEntity} found, <code>false</code> otherwise.
     * @return Retrieved, created {@link ArticleEntity}.
     * @author <a href="mailto:martynas@idega.com">Martynas Stak</a>
     */
    public ArticleEntity getArticleEntity(boolean createIfNotFound) {
        ArticleEntity article = getArticleDAO().getByUri(getResourcePath());

        if (createIfNotFound && article == null) {
            article = new ArticleEntity();
            article.setModificationDate(new Date(System.currentTimeMillis()));

            String articleURI = getResourcePath();
            if (articleURI.startsWith(CoreConstants.WEBDAV_SERVLET_URI))
                articleURI = articleURI.replaceFirst(CoreConstants.WEBDAV_SERVLET_URI, CoreConstants.EMPTY);
            if (articleURI.endsWith(CoreConstants.SLASH))
                articleURI = articleURI.substring(0, articleURI.lastIndexOf(CoreConstants.SLASH));

            article.setUri(articleURI);
        }

        if (createIfNotFound && article != null) {
            article.setCategories(getCategoryDao().addCategories(getCategories()));

            article = getArticleDAO().updateArticle(article);
        }

        return article;
    }

    public void setArticleEntity(ArticleEntity articleEntity) {
        //      this.articleEntity = articleEntity;
    }

    public boolean isPartOfArticleList() {
        return partOfArticleList;
    }

    public void setPartOfArticleList(boolean partOfArticleList) {
        this.partOfArticleList = partOfArticleList;
    }

    public ArticleLocalizedItemBean getLocalizedArticle() {
        if (this.localizedArticle == null || getLanguageChange() != null) {
            this.localizedArticle = new ArticleLocalizedItemBean(getLocale());
            //this.localizedArticle.setLocale(getLocale());
            this.localizedArticle.setArticleItem(this);
            try {
                if (isPersistToJCR() && this.getSession() != null) {
                    this.localizedArticle.setSession(this.getSession());
                }
            } catch (RepositoryException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            String thisLanguage = getLanguage();
            String fileLanguage = this.localizedArticle.getLanguage();
            if (!thisLanguage.equals(fileLanguage)) {
                throw new RuntimeException("Locale (" + getLocale() + ") inconsistency for article: "
                        + getResourcePath() + " and localizedArticle: " + this.localizedArticle.getResourcePath());
            }
        }
        return this.localizedArticle;
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#addImage(byte[], java.lang.String)
     */
    public void addImage(byte[] imageData, String contentType) {
        getLocalizedArticle().addImage(imageData, contentType);
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#clear()
     */
    @Override
    public void clear() {
        getLocalizedArticle().clear();
        this.resourcePath = null;
        this.availableInRequestedLanguage = false;
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getAsXML()
     */
    public String getAsXML() throws IOException, XMLException {
        return getLocalizedArticle().getAsXML();
    }

    /**
     * @return Author name expressed in string
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getAuthor()
     */
    public String getAuthor() {
        if (isDummyContentItem()) {
            return ArticleConstants.EMPTY;
        }
        return getLocalizedArticle().getAuthor();
    }

    /**
     * @return Text body of an article
     * Method is modified to resolve if dummy article is being edited
     */
    public String getBody() {
        if (isDummyContentItem()) {
            return ArticleConstants.EMPTY;
        }
        return getLocalizedArticle().getBody();
    }

    /**
     * @return Comments of an article
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getComment()
     */
    public String getComment() {
        return getLocalizedArticle().getComment();
    }

    public String getLinkToComments() {
        return getLocalizedArticle().getLinkToComments();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getContentFieldNames()
     */
    @Override
    public String[] getContentFieldNames() {
        return getLocalizedArticle().getContentFieldNames();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getContentItemPrefix()
     */
    @Override
    public String getContentItemPrefix() {
        return getLocalizedArticle().getContentItemPrefix();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getContentLanguage()
     */
    public String getContentLanguage() {
        return getLocalizedArticle().getContentLanguage();
    }

    /**
     * @return Text of article header.
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getHeadline()
     */
    public String getHeadline() {
        if (isDummyContentItem()) {
            return ArticleConstants.EMPTY;
        }
        return getLocalizedArticle().getHeadline();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getImages()
     */
    public List getImages() {
        return getLocalizedArticle().getImages();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getSource()
     */
    public String getSource() {
        return getLocalizedArticle().getSource();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getTeaser()
     */
    public String getTeaser() {
        if (isDummyContentItem()) {
            return ArticleConstants.EMPTY;
        }
        return getLocalizedArticle().getTeaser();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getToolbarActions()
     */
    @Override
    public String[] getToolbarActions() {
        return getLocalizedArticle().getToolbarActions();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#isUpdated()
     */
    public boolean isUpdated() {
        return getLocalizedArticle().isUpdated();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#prettifyBody()
     */
    protected void prettifyBody() {
        getLocalizedArticle().prettifyBody();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#removeImage(java.lang.Integer)
     */
    public void removeImage(Integer imageNumber) {
        getLocalizedArticle().removeImage(imageNumber);
    }

    /**
     * Add or change author name here.
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setAuthor(java.lang.String)
     */
    public void setAuthor(String s) {
        getLocalizedArticle().setAuthor(s);
    }

    /**
     * Add or change an article body text here.
     * @param body Text, that should be saved.
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setBody(java.lang.String)
     */
    public void setBody(String body) {
        getLocalizedArticle().setBody(body);
    }

    /**
     * Add or change an article comments here.
     * @param s Text, that should be saved.
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setComment(java.lang.String)
     */
    public void setComment(String s) {
        getLocalizedArticle().setComment(s);
    }

    public void setLinkToComments(String linkToComments) {
        getLocalizedArticle().setLinkToComments(linkToComments);
    }

    /**
     * Add or change an article header here, which shown in article creation dialog.
     * @param o Some object. Article header will be set as o.toString() value.
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setHeadline(java.lang.Object)
     */
    public void setHeadline(Object o) {
        getLocalizedArticle().setHeadline(o);
    }

    /**
     * Add or change an article header here, which shown in article creation dialog.
     * @param s Text of article header.
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setHeadline(java.lang.String)
     */
    public void setHeadline(String s) {
        getLocalizedArticle().setHeadline(s);
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setImages(java.util.List)
     */
    public void setImages(List l) {
        getLocalizedArticle().setImages(l);
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setPublished()
     */
    protected void setPublished() {
        getLocalizedArticle().setPublished();
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setSource(java.lang.String)
     */
    public void setSource(String s) {
        getLocalizedArticle().setSource(s);
    }

    /**
     * Add or change an article teaser text here. Teaser is shown in the article creation form.
     * @param s Teaser text.
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setTeaser(java.lang.String)
     */
    public void setTeaser(String s) {
        getLocalizedArticle().setTeaser(s);
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setUpdated(boolean)
     */
    public void setUpdated(boolean b) {
        getLocalizedArticle().setUpdated(b);
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setUpdated(java.lang.Boolean)
     */
    public void setUpdated(Boolean b) {
        getLocalizedArticle().setUpdated(b);
    }

    @Override
    public void store() throws IDOStoreException {
        ArticleEntity article = getArticleEntity(true);

        if (article == null || article.getId() == null)
            throw new IDOStoreException("Unable to create/edit article at " + getResourcePath());

        setArticleEntity(article);
        try {
            storeToSlide();
        } catch (Exception e) {
            throw new IDOStoreException("Failed storing to slide", e);
        }
    }

    /**
     * Method to save an article to *.xml file at store/content/files/cms/article server directory
     * @throws IDOStoreException
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#store()
     */
    public void storeToSlide() throws IDOStoreException {
        try {
            if (isPersistToWebDav())
                storeToWebDav();
            else if (isPersistToJCR())
                storeToJCR();
            getLocalizedArticle().store();

            IWMainApplication iwma = IWMainApplication.getDefaultIWMainApplication();
            if (iwma != null) {
                ArticleCacher cacher = ArticleCacher.getInstance(iwma);
                cacher.getCacheMap().clear();

                ContentUtil.removeCategoriesViewersFromCache();
            }
        } catch (ArticleStoreException ase) {
            throw ase;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        if (isPersistToJCR()) {
            try {
                commitJCRStore();
            } catch (RepositoryException e) {
                throw new IDOStoreException(e.getMessage());
            }
        }
    }

    protected void commitJCRStore() throws RepositoryException {
        getSession().save();
    }

    private void storeToWebDav() throws HttpException, IOException, RemoteException {
        IWUserContext iwuc = IWContext.getInstance();
        IWSlideSession session = getIWSlideSession(iwuc);
        WebdavRootResource rootResource = session.getWebdavRootResource();

        //   Setting the path for creating new file/creating localized version/updating existing file
        String articleFolderPath = getResourcePath();//"/content/files/public/article.lalala";//getResourcePath();

        boolean hadToCreate = session.createAllFoldersInPath(articleFolderPath);
        if (hadToCreate) {
            String fixedFolderURL = session.getURI(articleFolderPath);
            rootResource.proppatchMethod(fixedFolderURL, PROPERTY_CONTENT_TYPE, "LocalizedFile", true);
        } else {
            rootResource.proppatchMethod(articleFolderPath, PROPERTY_CONTENT_TYPE, "LocalizedFile", true);
        }

        rootResource.close();
    }

    private void storeToJCR() throws IOException, RepositoryException {
        //IWUserContext iwuc = IWContext.getInstance();
        //IWSlideSession session = getIWSlideSession(iwuc);
        Session session = getSession();
        //WebdavRootResource rootResource = session.getWebdavRootResource();

        //   Setting the path for creating new file/creating localized version/updating existing file
        String articleFolderPath = getResourcePath();

        RepositoryHelper helper = getRepositoryHelper();

        helper.createAllFoldersInPath(session, articleFolderPath);
        /*if (hadToCreate) {
           //String fixedFolderURL = session.getURI(articleFolderPath);
           String fixedFolderURL=articleFolderPath;
           Node node = getNode()
           rootResource.proppatchMethod(fixedFolderURL, PROPERTY_CONTENT_TYPE, "LocalizedFile", true);
        }
        else{
           rootResource.proppatchMethod(articleFolderPath, PROPERTY_CONTENT_TYPE, "LocalizedFile", true);
        }*/
        Node node = getNode();
        node.setProperty(CONTENT_TYPE_WITH_PREFIX, "LocalizedFile");
        node.save();
        //rootResource.close();

    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#tryPublish()
     */
    protected void tryPublish() {
        getLocalizedArticle().tryPublish();
    }

    /**
     * @return Article name
     * @see com.idega.content.bean.ContentItemBean#getName()
     */
    @Override
    public String getName() {
        return getLocalizedArticle().getName();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getDescription()
     */
    @Override
    public String getDescription() {
        return getLocalizedArticle().getDescription();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getItemType()
     */
    @Override
    public String getItemType() {
        return getLocalizedArticle().getItemType();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getCreatedByUserId()
     */
    @Override
    public int getCreatedByUserId() {
        return getLocalizedArticle().getCreatedByUserId();
    }

    /**
     * Add or change an article name
     * @param s Article name
     * @see com.idega.content.bean.ContentItemBean#setName(java.lang.String)
     */
    @Override
    public void setName(String s) {
        getLocalizedArticle().setName(s);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setDescription(java.lang.String)
     */
    @Override
    public void setDescription(String s) {
        getLocalizedArticle().setDescription(s);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setItemType(java.lang.String)
     */
    @Override
    public void setItemType(String s) {
        getLocalizedArticle().setItemType(s);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setCreatedByUserId(int)
     */
    @Override
    public void setCreatedByUserId(int id) {
        getLocalizedArticle().setCreatedByUserId(id);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getLocales()
     */
    @Override
    public Map getLocales() {
        return getLocalizedArticle().getLocales();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getPendingLocaleId()
     */
    @Override
    public String getPendingLocaleId() {
        return getLocalizedArticle().getPendingLocaleId();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setPendingLocaleId(java.lang.String)
     */
    @Override
    public void setPendingLocaleId(String localeId) {
        getLocalizedArticle().setPendingLocaleId(localeId);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getRequestedStatus()
     */
    @Override
    public String getRequestedStatus() {
        return getLocalizedArticle().getRequestedStatus();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setRequestedStatus(java.lang.String)
     */
    @Override
    public void setRequestedStatus(String requestedStatus) {
        getLocalizedArticle().setRequestedStatus(requestedStatus);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getAttachments()
     */
    @Override
    public List getAttachments() {
        return getLocalizedArticle().getAttachments();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setAttachment(java.util.List)
     */
    @Override
    public void setAttachment(List l) {
        getLocalizedArticle().setAttachment(l);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getCase()
     */
    @Override
    public ContentItemCase getCase() {
        return getLocalizedArticle().getCase();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setCase(com.idega.content.bean.ContentItemCase)
     */
    @Override
    public void setCase(ContentItemCase caseBean) {
        getLocalizedArticle().setCase(caseBean);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getStatus()
     */
    @Override
    public String getStatus() {
        return getLocalizedArticle().getStatus();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setStatus(java.lang.String)
     */
    @Override
    public void setStatus(String status) {
        getLocalizedArticle().setStatus(status);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#updateLocale()
     */
    @Override
    public void updateLocale() {
        getLocalizedArticle().updateLocale();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getCreationDate()
     */
    @Override
    public Timestamp getCreationDate() {
        return getLocalizedArticle().getCreationDate();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getVersionName()
     */
    @Override
    public String getVersionName() {
        return getLocalizedArticle().getVersionName();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setVersionName(java.lang.String)
     */
    @Override
    public void setVersionName(String name) {
        getLocalizedArticle().setVersionName(name);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getRendered()
     */
    @Override
    public Boolean getRendered() {
        return getLocalizedArticle().getRendered();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setRendered(boolean)
     */
    @Override
    public void setRendered(boolean render) {
        getLocalizedArticle().setRendered(render);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setRendered(java.lang.Boolean)
     */
    @Override
    public void setRendered(Boolean render) {
        getLocalizedArticle().setRendered(render);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#isAutoCreateResource()
     */
    @Override
    public boolean isAutoCreateResource() {

        return getLocalizedArticle().isAutoCreateResource();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setAutoCreateResource(boolean)
     */
    @Override
    public void setAutoCreateResource(boolean autoCreateResource) {

        getLocalizedArticle().setAutoCreateResource(autoCreateResource);
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#getExists()
     */
    @Override
    public boolean getExists() {

        return getLocalizedArticle().getExists();
    }

    /* (non-Javadoc)
     * @see com.idega.content.bean.ContentItemBean#setExists(boolean)
     */
    @Override
    public void setExists(boolean exists) {

        getLocalizedArticle().setExists(exists);
    }

    @Override
    public Object getValue(String fieldName) {
        return getLocalizedArticle().getValue(fieldName);
    }

    @Override
    public void setValue(String fieldName, Object value) {
        getLocalizedArticle().setValue(fieldName, value);
    }

    /*
     * If this is set this should return the base folder for storing articles.<br/>
     * By default it is '/files/cms/article'
     */
    public String getBaseFolderLocation() {
        if (this.baseFolderLocation != null) {
            return this.baseFolderLocation;
        } else {
            return ArticleUtil.getArticleBaseFolderPath();
        }
    }

    /*
     * This sets the base folder for storing articles,
     * something like '/files/cms/article'
     */
    public void setBaseFolderLocation(String path) {
        this.baseFolderLocation = path;
    }

    @Override
    public Locale getLocale() {
        return super.getLocale();
    }

    @Override
    public void setLocale(Locale locale) {
        super.setLocale(locale);
    }

    @Override
    public void setResourcePath(String resourcePath) {
        this.resourcePath = resourcePath;
        updateLocalizedArticleBean();
    }

    protected void updateLocalizedArticleBean() {
        String resourcePath = getResourcePath();
        String localizedResourcePath = calculateLocalizedResourcePath(resourcePath);
        getLocalizedArticle().setResourcePath(localizedResourcePath);
    }

    /**
     * <p>
     * Creates the resourcePath for the localized file (.../myarticle.article/en.xml)
     * </p>
     * @param resourcePath
     * @return
     */
    private String calculateLocalizedResourcePath(String resourcePath, String language) {
        if (!resourcePath.endsWith(StringHandler.SLASH)) {
            resourcePath += StringHandler.SLASH;
        }
        resourcePath += getArticleDefaultLocalizedFileName(language);
        return resourcePath;
    }

    private String calculateLocalizedResourcePath(String resourcePath) {
        return calculateLocalizedResourcePath(resourcePath, getLanguage());
    }

    private String getArticleDefaultLocalizedFileName(String language) {
        return language + ARTICLE_FILE_SUFFIX;
    }

    private String getArticleDefaultLocalizedResourcePath() {
        return getArticleDefaultLocalizedResourcePath(getLanguage());
    }

    private String getArticleDefaultLocalizedResourcePath(String language) {
        String resourcePath = getResourcePath();
        return calculateLocalizedResourcePath(resourcePath);
    }

    /**
     * This method returns the path of the article without the language part:
     * ../cms/article/YYYY/MM/YYYYMMDD-HHmm.article while ContentItem#getResourcePath()
     * returns the path to the actual resource ../cms/article/YYYY/MM/YYYYMMDD-HHmm.article/lang.xml
     *
     * @see ContentItem#getResourcePath()
     * @return Partial path of the article without the language part.
     */
    @Override
    public String getResourcePath() {
        String sResourcePath = this.resourcePath;
        if (StringUtil.isEmpty(sResourcePath) || sResourcePath.equals(CoreConstants.SLASH)) {
            sResourcePath = createArticlePath();
            setResourcePath(sResourcePath);
        }
        return sResourcePath;
    }

    public synchronized String createArticlePath() {
        String resourcePath = getGeneratedArticleResourcePath();
        int index = resourcePath.indexOf("." + CoreConstants.ARTICLE_FILENAME_SCOPE);
        if (index > -1) {
            String articlePath = resourcePath.substring(0,
                    index + CoreConstants.ARTICLE_FILENAME_SCOPE.length() + 1);
            LOGGER.info("Article path returned: " + articlePath);
            return articlePath;
        }
        LOGGER.warning("Resource path for article '" + resourcePath + "' does not contain article filename scope '."
                + CoreConstants.ARTICLE_FILENAME_SCOPE + "'.  The resource path is returned unchanged.");
        return resourcePath;
    }

    /**
     * Returns the path to the actual resource (xml-file) ../cms/article/YYYY/MM/YYYYMMDD-HHmm.article/lang.xml
     *
     * @see ContentItem#getResourcePath()
     * @return
     */
    private String getGeneratedArticleResourcePath() {
        makesureStandardFolderisCreated();
        String path = null;
        try {
            path = generateArticleResourcePath(CoreUtil.getIWContext());
        } catch (UnavailableIWContext e) {
            e.printStackTrace();
        }
        return path;
    }

    /**
     * Constructs the path for the article file as follows
     * First it gets the folder location of the article, this is typically generated by
     * ArticleUtil.getArticleYearMonthPath()
     * Then it appends a unique filename based on time, followed by .article
     * Example returnstring: /files/cms/article/2005/02/20050222-1246.article/en.xml
     * @param service
     * @return
     */
    protected String generateArticleResourcePath(IWContext iwc) {
        BuilderService service = null;
        try {
            service = BuilderServiceFactory.getBuilderService(iwc);
        } catch (RemoteException e) {
            e.printStackTrace();
            return null;
        }

        return service.generateResourcePath(getBaseFolderLocation(), CoreConstants.ARTICLE_FILENAME_SCOPE,
                CoreConstants.ARTICLE_FILENAME_SCOPE);
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#setLanguageChange(java.lang.String)
     */
    public void setLanguageChange(String s) {
        this.languageChange = s;
    }

    /* (non-Javadoc)
     * @see com.idega.block.article.bean.ArticleLocalizedItemBean#getLanguageChange()
     */
    public String getLanguageChange() {
        return this.languageChange;
    }

    /**
     * <p>
     * Makes sure the standard folder /cms/articles is created and that it has correct permissions.
     * </p>
     */
    private void makesureStandardFolderisCreated() {
        /*IWUserContext iwuc = CoreUtil.getIWContext();
        IWSlideService slideService = getIWSlideService(iwuc);
        String contentFolderPath = ArticleUtil.getContentRootPath();
        String articlePath = ArticleUtil.getArticleBaseFolderPath();
            
            
        try {
           //first make the folder:
           slideService.createAllFoldersInPathAsRoot(articlePath);
            
           //was not used? slideService.getWebdavResourceAuthenticatedAsRoot(contentFolderPath);
           AccessControlList aclList = slideService.getAccessControlList(contentFolderPath);
           AuthenticationBusiness authBusiness = ((IWSlideServiceBean)slideService).getAuthenticationBusiness();
            
           String editorRoleUri = authBusiness.getRoleURI(StandardRoles.ROLE_KEY_EDITOR);
           Ace editorAce = new Ace(editorRoleUri);
           editorAce.addPrivilege(Privilege.READ);
           editorAce.addPrivilege(Privilege.WRITE);
           AccessControlEntry editorEntry = new AccessControlEntry(editorAce,AccessControlEntry.PRINCIPAL_TYPE_ROLE);
           aclList.add(editorEntry);
            
           String authorRoleUri = authBusiness.getRoleURI(StandardRoles.ROLE_KEY_AUTHOR);
           Ace authorAce = new Ace(authorRoleUri);
           authorAce.addPrivilege(Privilege.READ);
           authorAce.addPrivilege(Privilege.WRITE);
           AccessControlEntry authorEntry = new AccessControlEntry(authorAce,AccessControlEntry.PRINCIPAL_TYPE_ROLE);
           aclList.add(authorEntry);
            
            
           slideService.storeAccessControlList(aclList);
            
           //debug:
           aclList = slideService.getAccessControlList(contentFolderPath);
            
        }
        catch (Exception e) {
           e.printStackTrace();
        }*/

    }

    /**
     * Loads the article (folder)
     */
    @Override
    protected boolean load(String path) throws IOException {
        return super.load(path);
    }

    private void setLanguageFromFilePath(String filePath) {
        String fileEnding = ARTICLE_FILE_SUFFIX;
        if (filePath.endsWith(fileEnding)) {
            String filePathWithoutEnding = filePath.substring(0, filePath.lastIndexOf(fileEnding));
            int lastIndexofSlash = filePathWithoutEnding.lastIndexOf("/");
            String language = filePathWithoutEnding.substring(lastIndexofSlash, filePathWithoutEnding.length());
            setLanguage(language);
        } else {
            throw new RuntimeException(
                    "filePath: " + filePath + " does not contain expected file ending: " + fileEnding);
        }
    }

    /**
     * Loads the article (folder)
     */
    @Override
    protected boolean load(WebdavExtendedResource webdavResource) throws IOException {
        WebdavExtendedResource localizedArticleFile = null;
        //First check if the resource is a folder, as it should be
        if (webdavResource.isCollection()) {

            WebdavResources resources = webdavResource.getChildResources();
            String userLanguageArticleResourcePath = getArticleDefaultLocalizedResourcePath();
            if (resources.isThereResourceName(userLanguageArticleResourcePath)) { //the language that the user has selected
                localizedArticleFile = (WebdavExtendedResource) resources
                        .getResource(userLanguageArticleResourcePath);
                setAvailableInSelectedLanguage();
            } else {
                //selected language not available:
                if (getAllowFallbackToSystemLanguage()) {
                    String systemLanguageArticleResourcePath = getArticleDefaultLocalizedResourcePath(
                            getSystemLanguage());//getArticleName(iwc.getIWMainApplication().getDefaultLocale());
                    if (resources.isThereResourceName(systemLanguageArticleResourcePath)) { //the language default in the system.
                        localizedArticleFile = (WebdavExtendedResource) resources
                                .getResource(systemLanguageArticleResourcePath);
                        setAvailableInSelectedLanguage();
                    } else {
                        setNotAvailableInSelectedLanguage();
                    }
                } else {
                    setNotAvailableInSelectedLanguage();
                }

            }
        } else {
            String path = getResourcePath();
            setLanguageFromFilePath(path);
            String parentFolder = webdavResource.getParentPath();
            setResourcePath(parentFolder);
            return load(parentFolder);
        }
        if (localizedArticleFile != null) {
            return getLocalizedArticle().load(localizedArticleFile);
        }
        return false;
    }

    /**
     * Loads the article (folder)
     * @throws RepositoryException
     */
    @Override
    protected boolean load(Node articleNode) throws IOException, RepositoryException {
        Node localizedArticleFile = null;
        //First check if the resource is a folder, as it should be
        if (articleNode.getPrimaryNodeType().isNodeType(RepositoryHelper.NODE_TYPE_FOLDER)) {

            NodeIterator resources = articleNode.getNodes();
            String userLanguageArticleResourcePath = getArticleDefaultLocalizedResourcePath();
            if (containsChildResourceWithPath(resources, userLanguageArticleResourcePath)) { //the language that the user has selected
                //localizedArticleFile = (WebdavExtendedResource) resources.getResource(userLanguageArticleResourcePath);
                localizedArticleFile = articleNode.getSession().getRootNode()
                        .getNode(userLanguageArticleResourcePath);
                setAvailableInSelectedLanguage();
            } else {
                //selected language not available:
                if (getAllowFallbackToSystemLanguage()) {
                    String systemLanguageArticleResourcePath = getArticleDefaultLocalizedResourcePath(
                            getSystemLanguage());//getArticleName(iwc.getIWMainApplication().getDefaultLocale());
                    if (containsChildResourceWithPath(resources, systemLanguageArticleResourcePath)) { //the language default in the system.
                        //localizedArticleFile = (WebdavExtendedResource) resources.getResource(systemLanguageArticleResourcePath);
                        localizedArticleFile = articleNode.getSession().getRootNode()
                                .getNode(systemLanguageArticleResourcePath);
                        setAvailableInSelectedLanguage();
                    } else {
                        setNotAvailableInSelectedLanguage();
                    }
                } else {
                    setNotAvailableInSelectedLanguage();
                }

            }
        } else {
            String path = getResourcePath();
            setLanguageFromFilePath(path);
            String parentFolder;
            parentFolder = articleNode.getParent().getPath();
            setResourcePath(parentFolder);
            return load(parentFolder);
        }
        if (localizedArticleFile != null) {
            return getLocalizedArticle().load(localizedArticleFile);
        }
        return false;
    }

    protected boolean containsChildResourceWithPath(NodeIterator resources, String childFullPath) {
        while (resources.hasNext()) {
            Node child = resources.nextNode();
            try {
                if (child.getPath().equals(childFullPath)) {
                    return true;
                }
            } catch (RepositoryException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * <p>
     * Returns the language set as default in the System
     * </p>
     * @return
     */
    public String getSystemLanguage() {
        Locale systemLocale = getSystemLocale();
        if (systemLocale != null) {
            return systemLocale.getLanguage();
        }
        return null;
    }

    public Locale getSystemLocale() {
        FacesContext context = FacesContext.getCurrentInstance();
        if (context != null) {
            return context.getApplication().getDefaultLocale();
        }
        return null;
    }

    public boolean getAllowFallbackToSystemLanguage() {
        return this.allowFallbackToSystemLanguage;
    }

    public void setAllowFallbackToSystemLanguage(boolean allow) {
        this.allowFallbackToSystemLanguage = allow;
    }

    public void setAvailableInSelectedLanguage() {
        this.availableInRequestedLanguage = true;
    }

    public void setNotAvailableInSelectedLanguage() {
        this.availableInRequestedLanguage = false;
        if (!getAllowFallbackToSystemLanguage()) {
            getLocalizedArticle().setHeadline("Article not available");
            getLocalizedArticle().setBody(ContentConstants.ARTICLE_NOT_AVAILABLE_BODY);
            setExists(true);
            setRendered(true);
            getLocalizedArticle().setRendered(true);
            getLocalizedArticle().setExists(true);
        }
    }

    /**
     * @return true if this article is available for the language of the locale set on this article item.
     */
    public boolean getAvailableInRequestedLanguage() {
        return this.availableInRequestedLanguage;
    }

    @Override
    public void delete() {
        getArticleDAO().remove(getArticleEntity(false));
        getLocalizedArticle().delete();
        this.localizedArticle = null;
        super.delete();

        ArticleCacher cacher = ArticleCacher.getInstance(IWMainApplication.getDefaultIWMainApplication());
        cacher.getCacheMap().clear();

        ContentUtil.removeCategoriesViewersFromCache();
    }

    /* (non-Javadoc)
     * @see javax.faces.event.ValueChangeListener#processValueChange(javax.faces.event.ValueChangeEvent)
     */
    @Override
    public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {

    }

    @Override
    public Timestamp getPublishedDate() {
        return getLocalizedArticle().getPublishedDate();
    }

    @Override
    public void setPublishedDate(Timestamp date) {
        getLocalizedArticle().setPublishedDate(date);
    }

    /**
     * Add or change categories of article here. Do not use UPPER case letters, use "-" instead of spaces. There should not be any simple spaces.
     * @param articleCategories Selected categories. Example: ",first-category,category,last-category,"
     */
    public void setArticleCategories(String articleCategories) {
        getLocalizedArticle().setArticleCategories(articleCategories);
    }

    public void setArticleCategories(Collection<String> categories) {
        if (ListUtil.isEmpty(categories)) {
            setArticleCategories(CoreConstants.EMPTY);
        }
        StringBuilder categoryString = new StringBuilder();
        for (java.util.Iterator<String> iter = categories.iterator(); iter.hasNext();) {
            categoryString.append(iter.next());
            if (iter.hasNext()) {
                categoryString.append(CoreConstants.COMMA);
            }
        }
        setArticleCategories(categoryString.toString());
    }

    @Override
    public boolean isSetPublishedDateByDefault() {
        return super.isSetPublishedDateByDefault();
    }

    @Override
    public void setSetPublishedDateByDefault(boolean setPublishedDateByDefault) {
        super.setSetPublishedDateByDefault(setPublishedDateByDefault);
    }

    /**
     *
     * @return Categories of an article
     */
    public List<String> getCategories() {
        return getLocalizedArticle().getCategories();
    }

    public String getFilesResourcePath() {
        String resourcesPath = getResourcePath();
        if (!resourcesPath.endsWith("/")) {
            resourcesPath = resourcesPath + "/";
        }
        resourcesPath = resourcesPath + "article-files/";
        return resourcesPath;
    }

}