/*
* $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;
}
}