/* * Created on May 19, 2006 */ package com.openedit.modules.workflow; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Element; import org.openedit.repository.ContentItem; import com.openedit.OpenEditException; import com.openedit.page.FileFinder; import com.openedit.page.Page; import com.openedit.page.PageProperty; import com.openedit.page.manage.PageManager; import com.openedit.users.User; import com.openedit.users.UserManager; import com.openedit.util.XmlUtil; public class WorkFlow { protected File fieldRoot; protected PageManager fieldPageManager; protected UserManager fieldUserManager; protected int fieldLevelCount = 0; private static final Log log = LogFactory.getLog(WorkFlow.class); protected long fieldLastModified = -2; protected ArrayList fieldWorkFlowListeners; public List listAllDrafts() throws OpenEditException { FileFinder finder = new FileFinder(); finder.setRoot(getRoot()); finder.setPageManager(getPageManager()); finder.addSkipFileName("*.xconf"); finder.addSkipFileName("WEB-INF"); finder.addSkipFileName("*/WEB-INF/*"); return finder.findPages("*.draft.*"); } public String getUserDescription( String inUserName ) { if ( inUserName == null || inUserName.length() == 0) { return ""; } User user = getUserManager().getUser(inUserName); if ( user != null) { return user.getShortDescription(); } return ""; } public ContentItem getLastVersion(Page inDraft ) throws OpenEditException { ContentItem revision = getPageManager().getLatestVersion(inDraft.getPath()); if( revision != null) { return revision; } return inDraft.getContentItem(); } public Page getOriginalPage(Page inDraft) throws OpenEditException { String dpath = inDraft.getPath(); int index = dpath.indexOf(".draft."); String path = dpath.substring(0,index); path = path + dpath.substring(index+6); Page org = getPageManager().getPage(path); return org; } public PageManager getPageManager() { return fieldPageManager; } public void setPageManager(PageManager inPageManager) { fieldPageManager = inPageManager; } public File getRoot() { return fieldRoot; } public void setRoot(File inRoot) { fieldRoot = inRoot; } public UserManager getUserManager() { return fieldUserManager; } public void setUserManager(UserManager inUserManager) { fieldUserManager = inUserManager; } public void approve(String inPath, User inUser) throws OpenEditException { Page draft = getPageManager().getPage(inPath); if(!draft.exists()) { log.error("No draft found to approve " + inPath); return; } //read in level count file loadLevelCount(); //see if we have levels configured if(getLevelCount() > 0) { int newLevel = findHighestApproval( inUser ); if( newLevel > 0) { int oldLevel = findExistingLevel(draft); if( oldLevel < newLevel) { saveLevel(draft, newLevel); } } if( newLevel < getLevelCount()) //then dont approve just yet { log.info("Requires more approval"); return; } } String orig = inPath.replaceAll("\\.draft", ""); Page dest = getPageManager().getPage(orig); dest.getContentItem().setAuthor(inUser.getUserName()); ContentItem rev = getLastVersion(draft); dest.getContentItem().setMessage("Approved: (" + rev.getAuthor() +" "+ rev.getMessage() +")"); dest.getContentItem().setType( ContentItem.TYPE_APPROVED); getPageManager().movePage(draft, dest); if( getLevelCount() > 0) { saveLevel(draft, 0); } firePageApproved(dest); } private void saveLevel(Page draft, int newLevel) throws OpenEditException { PageProperty property = new PageProperty("approve.level"); property.setValue(String.valueOf(newLevel )); draft.getPageSettings().putProperty(property); //save getPageManager().getPageSettingsManager().saveSetting(draft.getPageSettings()); } protected void loadLevelCount() throws OpenEditException { Page level = getPageManager().getPage("/openedit/components/html/workflow/settings.xml"); if( level.getLastModified().getTime() != fieldLastModified) { fieldLastModified = level.getLastModified().getTime(); Element root = new XmlUtil().getXml(level.getReader(), "UTF-8"); String text = root.elementText("levels"); if( text != null) { setLevelCount(Integer.parseInt(text)); } } } public int findExistingLevel( Page inDraft) { String existingLevel = inDraft.get("approve.level"); int oldLevel = 0; if( existingLevel != null) { oldLevel = Integer.parseInt(existingLevel); } return oldLevel; } public boolean canApprove( User inUser, Page inDraft) throws OpenEditException { if( inDraft.isDraft() && !inDraft.exists()) { return false; } if (inUser == null) { return false; } loadLevelCount(); if( getLevelCount() == 0) { if( inUser.hasPermission("oe.edit.approves") ) { return true; } else { return false; } } int power = findHighestApproval(inUser); if( power == 0) { return false; } int existing = findExistingLevel(inDraft); if( power > existing) { return true; } return false; } public int findHighestApproval(User inUser ) { int level = 0; for (int i = 1; i < getLevelCount()+1; i++) { if( inUser.hasPermission("oe.edit.approve.level" + i) ) { level = i; } } return level; } public void approveAll(User inUser) throws Exception { List pages = listAllDrafts(); for (Iterator iter = pages.iterator(); iter.hasNext();) { Page editPath = (Page) iter.next(); approve(editPath.getPath(), inUser); } } public void deleteDraft(String inPath, User inUser) throws OpenEditException { Page page = getPageManager().getPage(inPath); page.getContentItem().setAuthor(inUser.getUserName()); page.getContentItem().setMessage("Deleted Draft"); getPageManager().removePage(page); firePageDeleted(page); } public int getLevelCount() { return fieldLevelCount; } public void setLevelCount(int inLevelCount) { fieldLevelCount = inLevelCount; } public ArrayList getWorkFlowListeners() { if (fieldWorkFlowListeners == null) { fieldWorkFlowListeners = new ArrayList(); } return fieldWorkFlowListeners; } public void setWorkFlowListeners(ArrayList inWorkFlowListeners) { fieldWorkFlowListeners = inWorkFlowListeners; } protected void firePageApproved( Page inPage ) { for ( Iterator iter = getWorkFlowListeners().iterator(); iter.hasNext(); ) { WorkFlowListener listener = (WorkFlowListener) iter.next(); listener.pageApproved(inPage); } } protected void firePageDeleted( Page inPage ) { for ( Iterator iter = getWorkFlowListeners().iterator(); iter.hasNext(); ) { WorkFlowListener listener = (WorkFlowListener) iter.next(); listener.pageDeleted(inPage); } } public void addWorkFlowListener(WorkFlowListener inListener){ getWorkFlowListeners().add(inListener); } }