KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > bean > DocumentDetailsBean


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.web.bean;
18
19 import java.io.Serializable JavaDoc;
20 import java.text.MessageFormat JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import javax.faces.application.FacesMessage;
28 import javax.faces.context.FacesContext;
29 import javax.faces.event.ActionEvent;
30 import javax.transaction.UserTransaction JavaDoc;
31
32 import org.alfresco.error.AlfrescoRuntimeException;
33 import org.alfresco.model.ContentModel;
34 import org.alfresco.repo.content.MimetypeMap;
35 import org.alfresco.service.cmr.lock.LockService;
36 import org.alfresco.service.cmr.repository.ContentData;
37 import org.alfresco.service.cmr.repository.CopyService;
38 import org.alfresco.service.cmr.repository.NodeRef;
39 import org.alfresco.service.cmr.repository.NodeService;
40 import org.alfresco.service.cmr.repository.TemplateImageResolver;
41 import org.alfresco.service.cmr.repository.TemplateNode;
42 import org.alfresco.service.cmr.security.OwnableService;
43 import org.alfresco.service.cmr.version.Version;
44 import org.alfresco.service.cmr.version.VersionHistory;
45 import org.alfresco.service.cmr.version.VersionService;
46 import org.alfresco.service.namespace.NamespaceService;
47 import org.alfresco.service.namespace.QName;
48 import org.alfresco.web.app.Application;
49 import org.alfresco.web.app.context.UIContextService;
50 import org.alfresco.web.app.servlet.DownloadContentServlet;
51 import org.alfresco.web.bean.repository.MapNode;
52 import org.alfresco.web.bean.repository.Node;
53 import org.alfresco.web.bean.repository.Repository;
54 import org.alfresco.web.bean.wizard.NewRuleWizard;
55 import org.alfresco.web.ui.common.Utils;
56 import org.alfresco.web.ui.common.Utils.URLMode;
57 import org.alfresco.web.ui.common.component.UIActionLink;
58 import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
59 import org.apache.log4j.Logger;
60
61 /**
62  * Backing bean providing access to the details of a document
63  *
64  * @author gavinc
65  */

66 public class DocumentDetailsBean
67 {
68    private static final String JavaDoc MSG_SUCCESS_OWNERSHIP = "success_ownership";
69    private static final String JavaDoc MSG_HAS_FOLLOWING_CATEGORIES = "has_following_categories";
70    private static final String JavaDoc MSG_NO_CATEGORIES_APPLIED = "no_categories_applied";
71    private static final String JavaDoc MSG_ERROR_ASPECT_INLINEEDITABLE = "error_aspect_inlineeditable";
72    private static final String JavaDoc MSG_ERROR_ASPECT_VERSIONING = "error_aspect_versioning";
73    private static final String JavaDoc MSG_ERROR_ASPECT_CLASSIFY = "error_aspect_classify";
74    private static final String JavaDoc MSG_ERROR_WORKFLOW_REJECT = "error_workflow_reject";
75    private static final String JavaDoc MSG_ERROR_WORKFLOW_APPROVE = "error_workflow_approve";
76    private static final String JavaDoc MSG_ERROR_UPDATE_SIMPLEWORKFLOW = "error_update_simpleworkflow";
77    private static final String JavaDoc MSG_ERROR_UPDATE_CATEGORY = "error_update_category";
78
79    private static Logger logger = Logger.getLogger(DocumentDetailsBean.class);
80    
81    protected BrowseBean browseBean;
82    protected NodeService nodeService;
83    protected LockService lockService;
84    protected CopyService copyService;
85    protected VersionService versionService;
86    protected OwnableService ownableService;
87    protected NavigationBean navigator;
88    
89    private Map JavaDoc<String JavaDoc, Boolean JavaDoc> panels = new HashMap JavaDoc<String JavaDoc, Boolean JavaDoc>(5, 1.0f);
90    
91    private Map JavaDoc<String JavaDoc, Serializable JavaDoc> workflowProperties;
92    private NodeRef addedCategory;
93    private List JavaDoc categories;
94
95
96    /**
97     * Default constructor
98     */

99    public DocumentDetailsBean()
100    {
101       // initial state of some panels that don't use the default
102
panels.put("workflow-panel", false);
103       panels.put("category-panel", false);
104       panels.put("version-history-panel", false);
105    }
106    
107    /**
108     * Resets any state that may be held by this bean
109     */

110    public void reset()
111    {
112       // reset the workflow cache
113
this.workflowProperties = null;
114       
115       // reset the category caches
116
this.categories = null;
117       this.addedCategory = null;
118    }
119    
120    /**
121     * Returns the id of the current document
122     *
123     * @return The id
124     */

125    public String JavaDoc getId()
126    {
127       return getDocument().getId();
128    }
129    
130    /**
131     * Returns the name of the current document
132     *
133     * @return Name of the current document
134     */

135    public String JavaDoc getName()
136    {
137       return getDocument().getName();
138    }
139    
140    /**
141     * Returns the URL to download content for the current document
142     *
143     * @return Content url to download the current document
144     */

145    public String JavaDoc getUrl()
146    {
147       return (String JavaDoc)getDocument().getProperties().get("url");
148    }
149    
150    /**
151     * Returns the URL to the content for the current document
152     *
153     * @return Content url to the current document
154     */

155    public String JavaDoc getBrowserUrl()
156    {
157       return Utils.generateURL(FacesContext.getCurrentInstance(), getDocument(), URLMode.HTTP_INLINE);
158    }
159
160    /**
161     * Returns the download URL to the content for the current document
162     *
163     * @return Download url to the current document
164     */

165    public String JavaDoc getDownloadUrl()
166    {
167       return Utils.generateURL(FacesContext.getCurrentInstance(), getDocument(), URLMode.HTTP_DOWNLOAD);
168    }
169    
170    /**
171     * Returns the WebDAV URL for the current document
172     *
173     * @return The WebDAV url
174     */

175    public String JavaDoc getWebdavUrl()
176    {
177       return Utils.generateURL(FacesContext.getCurrentInstance(), getDocument(), URLMode.WEBDAV);
178    }
179    
180    /**
181     * Returns the URL to access the details page for the current document
182     *
183     * @return The bookmark URL
184     */

185    public String JavaDoc getBookmarkUrl()
186    {
187       return Utils.generateURL(FacesContext.getCurrentInstance(), getDocument(), URLMode.SHOW_DETAILS);
188    }
189    
190    /**
191     * Returns the CIFS path for the current document
192     *
193     * @return The CIFS path
194     */

195    public String JavaDoc getCifsPath()
196    {
197       return Utils.generateURL(FacesContext.getCurrentInstance(), getDocument(), URLMode.CIFS);
198    }
199    
200    /**
201     * Return the Alfresco NodeRef URL for the current document
202     *
203     * @return the Alfresco NodeRef URL
204     */

205    public String JavaDoc getNodeRefUrl()
206    {
207       return getDocument().getNodeRef().toString();
208    }
209    
210    /**
211     * Determines whether the current document is versionable
212     *
213     * @return true if the document has the versionable aspect
214     */

215    public boolean isVersionable()
216    {
217       return getDocument().hasAspect(ContentModel.ASPECT_VERSIONABLE);
218    }
219    
220    /**
221     * @return true if the current document has the 'inlineeditable' aspect applied
222     */

223    public boolean isInlineEditable()
224    {
225       return getDocument().hasAspect(ContentModel.ASPECT_INLINEEDITABLE);
226    }
227    
228    /**
229     * Returns a list of objects representing the versions of the
230     * current document
231     *
232     * @return List of previous versions
233     */

234    public List JavaDoc getVersionHistory()
235    {
236       List JavaDoc<MapNode> versions = new ArrayList JavaDoc<MapNode>();
237       
238       if (getDocument().hasAspect(ContentModel.ASPECT_VERSIONABLE))
239       {
240          VersionHistory history = this.versionService.getVersionHistory(getDocument().getNodeRef());
241    
242          if (history != null)
243          {
244             for (Version version : history.getAllVersions())
245             {
246                // create a map node representation of the version
247
MapNode clientVersion = new MapNode(version.getFrozenStateNodeRef());
248                clientVersion.put("versionLabel", version.getVersionLabel());
249                clientVersion.put("notes", version.getDescription());
250                clientVersion.put("author", version.getCreator());
251                clientVersion.put("versionDate", version.getCreatedDate());
252                clientVersion.put("url", DownloadContentServlet.generateBrowserURL(version.getFrozenStateNodeRef(),
253                      clientVersion.getName()));
254                
255                // add the client side version to the list
256
versions.add(clientVersion);
257             }
258          }
259       }
260       
261       return versions;
262    }
263    
264    /**
265     * Determines whether the current document has any categories applied
266     *
267     * @return true if the document has categories attached
268     */

269    public boolean isCategorised()
270    {
271       return getDocument().hasAspect(ContentModel.ASPECT_GEN_CLASSIFIABLE);
272    }
273    
274    /**
275     * Returns a list of objects representing the categories applied to the
276     * current document
277     *
278     * @return List of categories
279     */

280    public String JavaDoc getCategoriesOverviewHTML()
281    {
282       String JavaDoc html = null;
283       
284       if (isCategorised())
285       {
286          // we know for now that the general classifiable aspect only will be
287
// applied so we can retrive the categories property direclty
288
Collection JavaDoc categories = (Collection JavaDoc)this.nodeService.getProperty(this.browseBean.getDocument().getNodeRef(),
289                ContentModel.PROP_CATEGORIES);
290          
291          if (categories == null || categories.size() == 0)
292          {
293             html = Application.getMessage(FacesContext.getCurrentInstance(), MSG_NO_CATEGORIES_APPLIED);
294          }
295          else
296          {
297             StringBuilder JavaDoc builder = new StringBuilder JavaDoc(Application.getMessage(FacesContext.getCurrentInstance(),
298                   MSG_HAS_FOLLOWING_CATEGORIES));
299             
300             builder.append("<ul>");
301             for (Object JavaDoc obj : categories)
302             {
303                if (obj instanceof NodeRef)
304                {
305                   if (this.nodeService.exists((NodeRef)obj))
306                   {
307                      builder.append("<li>");
308                      builder.append(Repository.getNameForNode(this.nodeService, (NodeRef)obj));
309                      builder.append("</li>");
310                   }
311                }
312             }
313             builder.append("</ul>");
314             
315             html = builder.toString();
316          }
317       }
318       
319       return html;
320    }
321
322    /**
323     * Event handler called to setup the categories for editing
324     *
325     * @param event The event
326     */

327    public void setupCategoriesForEdit(ActionEvent event)
328    {
329       this.categories = (List JavaDoc)this.nodeService.getProperty(this.browseBean.getDocument().getNodeRef(),
330                ContentModel.PROP_CATEGORIES);
331    }
332    
333    /**
334     * Returns a Map of the initial categories on the node keyed by the NodeRef
335     *
336     * @return Map of initial categories
337     */

338    public List JavaDoc getCategories()
339    {
340       return this.categories;
341    }
342    
343    /**
344     * Sets the categories Map
345     *
346     * @param categories
347     */

348    public void setCategories(List JavaDoc categories)
349    {
350       this.categories = categories;
351    }
352    
353    /**
354     * Returns the last category added from the multi value editor
355     *
356     * @return The last category added
357     */

358    public NodeRef getAddedCategory()
359    {
360       return this.addedCategory;
361    }
362
363    /**
364     * Sets the category added from the multi value editor
365     *
366     * @param addedCategory The added category
367     */

368    public void setAddedCategory(NodeRef addedCategory)
369    {
370       this.addedCategory = addedCategory;
371    }
372    
373    /**
374     * Updates the categories for the current document
375     *
376     * @return The outcome
377     */

378    public String JavaDoc saveCategories()
379    {
380       String JavaDoc outcome = "cancel";
381       
382       UserTransaction JavaDoc tx = null;
383       
384       try
385       {
386          FacesContext context = FacesContext.getCurrentInstance();
387          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
388          tx.begin();
389          
390          // firstly retrieve all the properties for the current node
391
Map JavaDoc<QName, Serializable JavaDoc> updateProps = this.nodeService.getProperties(
392                getDocument().getNodeRef());
393          
394          // create a node ref representation of the selected id and set the new properties
395
updateProps.put(ContentModel.PROP_CATEGORIES, (Serializable JavaDoc)this.categories);
396          
397          // set the properties on the node
398
this.nodeService.setProperties(getDocument().getNodeRef(), updateProps);
399          
400          // commit the transaction
401
tx.commit();
402          
403          // reset the state of the current document so it reflects the changes just made
404
getDocument().reset();
405          
406          outcome = "finish";
407       }
408       catch (Throwable JavaDoc e)
409       {
410          try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
411          Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
412                FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_CATEGORY), e.getMessage()), e);
413       }
414       
415       return outcome;
416    }
417    
418    /**
419     * Returns an overview summary of the current state of the attached
420     * workflow (if any)
421     *
422     * @return Summary HTML
423     */

424    public String JavaDoc getWorkflowOverviewHTML()
425    {
426       String JavaDoc html = null;
427       
428       if (getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
429       {
430          // get the simple workflow aspect properties
431
Map JavaDoc<String JavaDoc, Object JavaDoc> props = getDocument().getProperties();
432
433          String JavaDoc approveStepName = (String JavaDoc)props.get(
434                ContentModel.PROP_APPROVE_STEP.toString());
435          String JavaDoc rejectStepName = (String JavaDoc)props.get(
436                ContentModel.PROP_REJECT_STEP.toString());
437          
438          Boolean JavaDoc approveMove = (Boolean JavaDoc)props.get(
439                ContentModel.PROP_APPROVE_MOVE.toString());
440          Boolean JavaDoc rejectMove = (Boolean JavaDoc)props.get(
441                ContentModel.PROP_REJECT_MOVE.toString());
442          
443          NodeRef approveFolder = (NodeRef)props.get(
444                ContentModel.PROP_APPROVE_FOLDER.toString());
445          NodeRef rejectFolder = (NodeRef)props.get(
446                ContentModel.PROP_REJECT_FOLDER.toString());
447          
448          String JavaDoc approveFolderName = null;
449          String JavaDoc rejectFolderName = null;
450          
451          // get the approve folder name
452
if (approveFolder != null)
453          {
454             Node node = new Node(approveFolder);
455             approveFolderName = node.getName();
456          }
457          
458          // get the reject folder name
459
if (rejectFolder != null)
460          {
461             Node node = new Node(rejectFolder);
462             rejectFolderName = node.getName();
463          }
464          
465          StringBuilder JavaDoc builder = new StringBuilder JavaDoc();
466          
467          // calculate the approve action string
468
String JavaDoc action = null;
469          if (approveMove.booleanValue())
470          {
471             action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
472          }
473          else
474          {
475             action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
476          }
477          
478          String JavaDoc docActionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "document_action");
479          Object JavaDoc[] params = new Object JavaDoc[] {action, approveFolderName, approveStepName};
480          builder.append(MessageFormat.format(docActionPattern, params));
481          
482          // add details of the reject step if there is one
483
if (rejectStepName != null && rejectMove != null && rejectFolderName != null)
484          {
485             if (rejectMove.booleanValue())
486             {
487                action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
488             }
489             else
490             {
491                action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
492             }
493             
494             builder.append("<p>");
495             params = new Object JavaDoc[] {action, rejectFolderName, rejectStepName};
496             builder.append(MessageFormat.format(docActionPattern, params));
497             builder.append("</p>");
498          }
499          
500          html = builder.toString();
501       }
502          
503       return html;
504    }
505    
506    /**
507     * Returns the properties for the attached workflow as a map
508     *
509     * @return Properties of the attached workflow, null if there is no workflow
510     */

511    public Map JavaDoc<String JavaDoc, Serializable JavaDoc> getWorkflowProperties()
512    {
513       if (this.workflowProperties == null &&
514           getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
515       {
516          // get the exisiting properties for the document
517
Map JavaDoc<String JavaDoc, Object JavaDoc> props = getDocument().getProperties();
518          
519          String JavaDoc approveStepName = (String JavaDoc)props.get(
520                ContentModel.PROP_APPROVE_STEP.toString());
521          String JavaDoc rejectStepName = (String JavaDoc)props.get(
522                ContentModel.PROP_REJECT_STEP.toString());
523          
524          Boolean JavaDoc approveMove = (Boolean JavaDoc)props.get(
525                ContentModel.PROP_APPROVE_MOVE.toString());
526          Boolean JavaDoc rejectMove = (Boolean JavaDoc)props.get(
527                ContentModel.PROP_REJECT_MOVE.toString());
528          
529          NodeRef approveFolder = (NodeRef)props.get(
530                ContentModel.PROP_APPROVE_FOLDER.toString());
531          NodeRef rejectFolder = (NodeRef)props.get(
532                ContentModel.PROP_REJECT_FOLDER.toString());
533
534          // put the workflow properties in a separate map for use by the JSP
535
this.workflowProperties = new HashMap JavaDoc<String JavaDoc, Serializable JavaDoc>(7);
536          this.workflowProperties.put(NewRuleWizard.PROP_APPROVE_STEP_NAME,
537                approveStepName);
538          this.workflowProperties.put(NewRuleWizard.PROP_APPROVE_ACTION,
539                approveMove ? "move" : "copy");
540          this.workflowProperties.put(NewRuleWizard.PROP_APPROVE_FOLDER, approveFolder);
541          
542          if (rejectStepName == null || rejectMove == null || rejectFolder == null)
543          {
544             this.workflowProperties.put(NewRuleWizard.PROP_REJECT_STEP_PRESENT, "no");
545          }
546          else
547          {
548             this.workflowProperties.put(NewRuleWizard.PROP_REJECT_STEP_PRESENT,
549                   "yes");
550             this.workflowProperties.put(NewRuleWizard.PROP_REJECT_STEP_NAME,
551                   rejectStepName);
552             this.workflowProperties.put(NewRuleWizard.PROP_REJECT_ACTION,
553                   rejectMove ? "move" : "copy");
554             this.workflowProperties.put(NewRuleWizard.PROP_REJECT_FOLDER,
555                   rejectFolder);
556          }
557       }
558       
559       return this.workflowProperties;
560    }
561    
562    /**
563     *
564     * @return
565     */

566    public String JavaDoc cancelWorkflowEdit()
567    {
568       // resets the workflow properties map so any changes made
569
// don't appear to be persisted
570
this.workflowProperties.clear();
571       this.workflowProperties = null;
572       return "cancel";
573    }
574    
575    /**
576     * Saves the details of the workflow stored in workflowProperties
577     * to the current document
578     *
579     * @return The outcome string
580     */

581    public String JavaDoc saveWorkflow()
582    {
583       String JavaDoc outcome = "cancel";
584       
585       UserTransaction JavaDoc tx = null;
586       
587       try
588       {
589          FacesContext context = FacesContext.getCurrentInstance();
590          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
591          tx.begin();
592          
593          // firstly retrieve all the properties for the current node
594
Map JavaDoc<QName, Serializable JavaDoc> updateProps = this.nodeService.getProperties(
595                getDocument().getNodeRef());
596          
597          // update the simple workflow properties
598

599          // set the approve step name
600
updateProps.put(ContentModel.PROP_APPROVE_STEP,
601                this.workflowProperties.get(NewRuleWizard.PROP_APPROVE_STEP_NAME));
602          
603          // specify whether the approve step will copy or move the content
604
boolean approveMove = true;
605          String JavaDoc approveAction = (String JavaDoc)this.workflowProperties.get(NewRuleWizard.PROP_APPROVE_ACTION);
606          if (approveAction != null && approveAction.equals("copy"))
607          {
608             approveMove = false;
609          }
610          updateProps.put(ContentModel.PROP_APPROVE_MOVE, Boolean.valueOf(approveMove));
611          
612          // create node ref representation of the destination folder
613
updateProps.put(ContentModel.PROP_APPROVE_FOLDER,
614                this.workflowProperties.get(NewRuleWizard.PROP_APPROVE_FOLDER));
615          
616          // determine whether there should be a reject step
617
boolean requireReject = true;
618          String JavaDoc rejectStepPresent = (String JavaDoc)this.workflowProperties.get(
619                NewRuleWizard.PROP_REJECT_STEP_PRESENT);
620          if (rejectStepPresent != null && rejectStepPresent.equals("no"))
621          {
622             requireReject = false;
623          }
624          
625          if (requireReject)
626          {
627             // set the reject step name
628
updateProps.put(ContentModel.PROP_REJECT_STEP,
629                   this.workflowProperties.get(NewRuleWizard.PROP_REJECT_STEP_NAME));
630          
631             // specify whether the reject step will copy or move the content
632
boolean rejectMove = true;
633             String JavaDoc rejectAction = (String JavaDoc)this.workflowProperties.get(
634                   NewRuleWizard.PROP_REJECT_ACTION);
635             if (rejectAction != null && rejectAction.equals("copy"))
636             {
637                rejectMove = false;
638             }
639             updateProps.put(ContentModel.PROP_REJECT_MOVE, Boolean.valueOf(rejectMove));
640
641             // create node ref representation of the destination folder
642
updateProps.put(ContentModel.PROP_REJECT_FOLDER,
643                   this.workflowProperties.get(NewRuleWizard.PROP_REJECT_FOLDER));
644          }
645          else
646          {
647             // set all the reject properties to null to signify there should
648
// be no reject step
649
updateProps.put(ContentModel.PROP_REJECT_STEP, null);
650             updateProps.put(ContentModel.PROP_REJECT_MOVE, null);
651             updateProps.put(ContentModel.PROP_REJECT_FOLDER, null);
652          }
653          
654          // set the properties on the node
655
this.nodeService.setProperties(getDocument().getNodeRef(), updateProps);
656          
657          // commit the transaction
658
tx.commit();
659          
660          // reset the state of the current document so it reflects the changes just made
661
getDocument().reset();
662          
663          outcome = "finish";
664       }
665       catch (Throwable JavaDoc e)
666       {
667          try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
668          Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
669                FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_SIMPLEWORKFLOW), e.getMessage()), e);
670       }
671       
672       return outcome;
673    }
674    
675    /**
676     * Returns the name of the approve step of the attached workflow
677     *
678     * @return The name of the approve step or null if there is no workflow
679     */

680    public String JavaDoc getApproveStepName()
681    {
682       String JavaDoc approveStepName = null;
683       
684       if (getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
685       {
686          approveStepName = (String JavaDoc)getDocument().getProperties().get(
687                ContentModel.PROP_APPROVE_STEP.toString());
688       }
689       
690       return approveStepName;
691    }
692    
693    /**
694     * Event handler called to handle the approve step of the simple workflow
695     *
696     * @param event The event that was triggered
697     */

698    public void approve(ActionEvent event)
699    {
700       UIActionLink link = (UIActionLink)event.getComponent();
701       Map JavaDoc<String JavaDoc, String JavaDoc> params = link.getParameterMap();
702       String JavaDoc id = params.get("id");
703       if (id == null || id.length() == 0)
704       {
705          throw new AlfrescoRuntimeException("approve called without an id");
706       }
707       
708       NodeRef docNodeRef = new NodeRef(Repository.getStoreRef(), id);
709       Node docNode = new Node(docNodeRef);
710       
711       if (docNode.hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW) == false)
712       {
713          throw new AlfrescoRuntimeException("You can not approve a document that is not part of a workflow");
714       }
715       
716       // get the simple workflow aspect properties
717
Map JavaDoc<String JavaDoc, Object JavaDoc> props = docNode.getProperties();
718       
719       Boolean JavaDoc approveMove = (Boolean JavaDoc)props.get(ContentModel.PROP_APPROVE_MOVE.toString());
720       NodeRef approveFolder = (NodeRef)props.get(ContentModel.PROP_APPROVE_FOLDER.toString());
721       
722       UserTransaction JavaDoc tx = null;
723       try
724       {
725          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
726          tx.begin();
727          
728          // first we need to take off the simpleworkflow aspect
729
this.nodeService.removeAspect(docNodeRef, ContentModel.ASPECT_SIMPLE_WORKFLOW);
730          
731          if (approveMove.booleanValue())
732          {
733             // move the document to the specified folder
734
String JavaDoc qname = QName.createValidLocalName(docNode.getName());
735             this.nodeService.moveNode(docNodeRef, approveFolder, ContentModel.ASSOC_CONTAINS,
736                   QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname));
737          }
738          else
739          {
740             // copy the document to the specified folder
741
String JavaDoc qname = QName.createValidLocalName(docNode.getName());
742             this.copyService.copy(docNodeRef, approveFolder, ContentModel.ASSOC_CONTAINS,
743                   QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname));
744          }
745          
746          // commit the transaction
747
tx.commit();
748          
749          // if this was called via the document details dialog we need to reset the document node
750
if (getDocument() != null)
751          {
752             getDocument().reset();
753          }
754          
755          // also make sure the UI will get refreshed
756
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
757          
758          if (logger.isDebugEnabled())
759          {
760             String JavaDoc movedCopied = approveMove ? "moved" : "copied";
761             logger.debug("Document has been approved and " + movedCopied + " to folder with id of " +
762                   approveFolder.getId());
763          }
764       }
765       catch (Throwable JavaDoc e)
766       {
767          // rollback the transaction
768
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
769          Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
770                FacesContext.getCurrentInstance(), MSG_ERROR_WORKFLOW_APPROVE), e.getMessage()), e);
771       }
772    }
773    
774    /**
775     * Returns the name of the reject step of the attached workflow
776     *
777     * @return The name of the reject step or null if there is no workflow
778     */

779    public String JavaDoc getRejectStepName()
780    {
781       String JavaDoc approveStepName = null;
782       
783       if (getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
784       {
785          approveStepName = (String JavaDoc)getDocument().getProperties().get(
786                ContentModel.PROP_REJECT_STEP.toString());
787       }
788       
789       return approveStepName;
790    }
791    
792    /**
793     * Event handler called to handle the approve step of the simple workflow
794     *
795     * @param event The event that was triggered
796     */

797    public void reject(ActionEvent event)
798    {
799       UIActionLink link = (UIActionLink)event.getComponent();
800       Map JavaDoc<String JavaDoc, String JavaDoc> params = link.getParameterMap();
801       String JavaDoc id = params.get("id");
802       if (id == null || id.length() == 0)
803       {
804          throw new AlfrescoRuntimeException("reject called without an id");
805       }
806       
807       NodeRef docNodeRef = new NodeRef(Repository.getStoreRef(), id);
808       Node docNode = new Node(docNodeRef);
809       
810       if (docNode.hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW) == false)
811       {
812          throw new AlfrescoRuntimeException("You can not reject a document that is not part of a workflow");
813       }
814       
815       // get the simple workflow aspect properties
816
Map JavaDoc<String JavaDoc, Object JavaDoc> props = docNode.getProperties();
817       
818       String JavaDoc rejectStep = (String JavaDoc)props.get(ContentModel.PROP_REJECT_STEP.toString());
819       Boolean JavaDoc rejectMove = (Boolean JavaDoc)props.get(ContentModel.PROP_REJECT_MOVE.toString());
820       NodeRef rejectFolder = (NodeRef)props.get(ContentModel.PROP_REJECT_FOLDER.toString());
821       
822       if (rejectStep == null && rejectMove == null && rejectFolder == null)
823       {
824          throw new AlfrescoRuntimeException("The workflow does not have a reject step defined");
825       }
826       
827       UserTransaction JavaDoc tx = null;
828       try
829       {
830          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
831          tx.begin();
832          
833          // first we need to take off the simpleworkflow aspect
834
this.nodeService.removeAspect(docNodeRef, ContentModel.ASPECT_SIMPLE_WORKFLOW);
835          
836          if (rejectMove.booleanValue())
837          {
838             // move the document to the specified folder
839
String JavaDoc qname = QName.createValidLocalName(docNode.getName());
840             this.nodeService.moveNode(docNodeRef, rejectFolder, ContentModel.ASSOC_CONTAINS,
841                   QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname));
842          }
843          else
844          {
845             // copy the document to the specified folder
846
String JavaDoc qname = QName.createValidLocalName(docNode.getName());
847             this.copyService.copy(docNodeRef, rejectFolder, ContentModel.ASSOC_CONTAINS,
848                   QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname));
849          }
850          
851          // commit the transaction
852
tx.commit();
853          
854          // if this was called via the document details dialog we need to reset the document node
855
if (getDocument() != null)
856          {
857             getDocument().reset();
858          }
859          
860          // also make sure the UI will get refreshed
861
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
862          
863          if (logger.isDebugEnabled())
864          {
865             String JavaDoc movedCopied = rejectMove ? "moved" : "copied";
866             logger.debug("Document has been rejected and " + movedCopied + " to folder with id of " +
867                   rejectFolder.getId());
868          }
869       }
870       catch (Throwable JavaDoc e)
871       {
872          // rollback the transaction
873
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
874          Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
875                FacesContext.getCurrentInstance(), MSG_ERROR_WORKFLOW_REJECT), e.getMessage()), e);
876       }
877    }
878    
879    /**
880     * Applies the classifiable aspect to the current document
881     */

882    public void applyClassifiable()
883    {
884       UserTransaction JavaDoc tx = null;
885       
886       try
887       {
888          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
889          tx.begin();
890          
891          // add the general classifiable aspect to the node
892
this.nodeService.addAspect(getDocument().getNodeRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, null);
893          
894          // commit the transaction
895
tx.commit();
896          
897          // reset the state of the current document
898
getDocument().reset();
899       }
900       catch (Throwable JavaDoc e)
901       {
902          // rollback the transaction
903
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
904          Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
905                FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_CLASSIFY), e.getMessage()), e);
906       }
907    }
908    
909    /**
910     * Applies the versionable aspect to the current document
911     */

912    public void applyVersionable()
913    {
914       UserTransaction JavaDoc tx = null;
915       
916       try
917       {
918          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
919          tx.begin();
920          
921          // add the versionable aspect to the node
922
this.nodeService.addAspect(getDocument().getNodeRef(), ContentModel.ASPECT_VERSIONABLE, null);
923          
924          // commit the transaction
925
tx.commit();
926          
927          // reset the state of the current document
928
getDocument().reset();
929       }
930       catch (Throwable JavaDoc e)
931       {
932          // rollback the transaction
933
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
934          Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
935                FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_VERSIONING), e.getMessage()), e);
936       }
937    }
938    
939    /**
940     * Applies the inlineeditable aspect to the current document
941     */

942    public String JavaDoc applyInlineEditable()
943    {
944       UserTransaction JavaDoc tx = null;
945       
946       try
947       {
948          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
949          tx.begin();
950          
951          // add the inlineeditable aspect to the node
952
Map JavaDoc<QName, Serializable JavaDoc> props = new HashMap JavaDoc<QName, Serializable JavaDoc>(1, 1.0f);
953          String JavaDoc contentType = null;
954          ContentData contentData = (ContentData)getDocument().getProperties().get(ContentModel.PROP_CONTENT);
955          if (contentData != null)
956          {
957             contentType = contentData.getMimetype();
958          }
959          if (contentType != null)
960          {
961             // set the property to true by default if the filetype is text/HTML content
962
if (MimetypeMap.MIMETYPE_HTML.equals(contentType) ||
963                 MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(contentType) ||
964                 MimetypeMap.MIMETYPE_XML.equals(contentType) ||
965                 MimetypeMap.MIMETYPE_TEXT_CSS.equals(contentType))
966             {
967                props.put(ContentModel.PROP_EDITINLINE, true);
968             }
969          }
970          this.nodeService.addAspect(getDocument().getNodeRef(), ContentModel.ASPECT_INLINEEDITABLE, props);
971          
972          // commit the transaction
973
tx.commit();
974          
975          // reset the state of the current document
976
getDocument().reset();
977       }
978       catch (Throwable JavaDoc e)
979       {
980          // rollback the transaction
981
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
982          Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
983                FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_INLINEEDITABLE), e.getMessage()), e);
984       }
985       
986       // force recreation of the details view - this means the properties sheet component will reinit
987
return "showDocDetails";
988    }
989    
990    /**
991     * Navigates to next item in the list of content for the current Space
992     */

993    public void nextItem(ActionEvent event)
994    {
995       UIActionLink link = (UIActionLink)event.getComponent();
996       Map JavaDoc<String JavaDoc, String JavaDoc> params = link.getParameterMap();
997       String JavaDoc id = params.get("id");
998       if (id != null && id.length() != 0)
999       {
1000         List JavaDoc<Node> nodes = this.browseBean.getContent();
1001         if (nodes.size() > 1)
1002         {
1003            // perform a linear search - this is slow but stateless
1004
// otherwise we would have to manage state of last selected node
1005
// this gets very tricky as this bean is instantiated once and never
1006
// reset - it does not know when the document has changed etc.
1007
for (int i=0; i<nodes.size(); i++)
1008            {
1009               if (id.equals(nodes.get(i).getId()) == true)
1010               {
1011                  Node next;
1012                  // found our item - navigate to next
1013
if (i != nodes.size() - 1)
1014                  {
1015                     next = nodes.get(i + 1);
1016                  }
1017                  else
1018                  {
1019                     // handle wrapping case
1020
next = nodes.get(0);
1021                  }
1022                  
1023                  // prepare for showing details for this node
1024
this.browseBean.setupContentAction(next.getId(), false);
1025                  break;
1026               }
1027            }
1028         }
1029      }
1030   }
1031   
1032   /**
1033    * Navigates to the previous item in the list of content for the current Space
1034    */

1035   public void previousItem(ActionEvent event)
1036   {
1037      UIActionLink link = (UIActionLink)event.getComponent();
1038      Map JavaDoc<String JavaDoc, String JavaDoc> params = link.getParameterMap();
1039      String JavaDoc id = params.get("id");
1040      if (id != null && id.length() != 0)
1041      {
1042         List JavaDoc<Node> nodes = this.browseBean.getContent();
1043         if (nodes.size() > 1)
1044         {
1045            // see above
1046
for (int i=0; i<nodes.size(); i++)
1047            {
1048               if (id.equals(nodes.get(i).getId()) == true)
1049               {
1050                  Node previous;
1051                  // found our item - navigate to previous
1052
if (i != 0)
1053                  {
1054                     previous = nodes.get(i - 1);
1055                  }
1056                  else
1057                  {
1058                     // handle wrapping case
1059
previous = nodes.get(nodes.size() - 1);
1060                  }
1061                  
1062                  // prepare for showing details for this node
1063
this.browseBean.setupContentAction(previous.getId(), false);
1064                  break;
1065               }
1066            }
1067         }
1068      }
1069   }
1070   
1071   /**
1072    * Action Handler to take Ownership of the current document
1073    */

1074   public void takeOwnership(ActionEvent event)
1075   {
1076      UserTransaction JavaDoc tx = null;
1077      
1078      try
1079      {
1080         tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
1081         tx.begin();
1082         
1083         this.ownableService.takeOwnership(getDocument().getNodeRef());
1084         
1085         FacesContext context = FacesContext.getCurrentInstance();
1086         String JavaDoc msg = Application.getMessage(context, MSG_SUCCESS_OWNERSHIP);
1087         FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
1088         context.addMessage(event.getComponent().getClientId(context), facesMsg);
1089         
1090         // commit the transaction
1091
tx.commit();
1092      }
1093      catch (Throwable JavaDoc e)
1094      {
1095         // rollback the transaction
1096
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
1097         Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
1098               FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), e.getMessage()), e);
1099      }
1100   }
1101   
1102   /**
1103    * Save the state of the panel that was expanded/collapsed
1104    */

1105   public void expandPanel(ActionEvent event)
1106   {
1107      if (event instanceof ExpandedEvent)
1108      {
1109         String JavaDoc id = event.getComponent().getId();
1110         // we prefix some panels with "no-" which we remove to give consistent behaviour in the UI
1111
if (id.startsWith("no-") == true)
1112         {
1113            id = id.substring(3);
1114         }
1115         this.panels.put(id, ((ExpandedEvent)event).State);
1116      }
1117   }
1118   
1119   /**
1120    * Returns a model for use by a template on the Document Details page.
1121    *
1122    * @return model containing current document and current space info.
1123    */

1124   public Map JavaDoc getTemplateModel()
1125   {
1126      HashMap JavaDoc model = new HashMap JavaDoc(3, 1.0f);
1127      
1128      FacesContext fc = FacesContext.getCurrentInstance();
1129      TemplateNode documentNode = new TemplateNode(getDocument().getNodeRef(),
1130              Repository.getServiceRegistry(fc), imageResolver);
1131      model.put("document", documentNode);
1132      TemplateNode spaceNode = new TemplateNode(this.navigator.getCurrentNode().getNodeRef(),
1133              Repository.getServiceRegistry(fc), imageResolver);
1134      model.put("space", spaceNode);
1135      
1136      return model;
1137   }
1138   
1139   /** Template Image resolver helper */
1140   private TemplateImageResolver imageResolver = new TemplateImageResolver()
1141   {
1142       public String JavaDoc resolveImagePathForName(String JavaDoc filename, boolean small)
1143       {
1144           return Utils.getFileTypeImage(filename, small);
1145       }
1146   };
1147   
1148   /**
1149    * Returns whether the current document is locked
1150    *
1151    * @return true if the document is checked out
1152    */

1153   public boolean isLocked()
1154   {
1155      return Repository.isNodeLocked(getDocument(), this.lockService);
1156   }
1157   
1158   /**
1159    * Returns whether the current document is a working copy
1160    *
1161    * @return true if the document is a working copy
1162    */

1163   public boolean isWorkingCopy()
1164   {
1165      return getDocument().hasAspect(ContentModel.ASPECT_WORKING_COPY);
1166   }
1167   
1168   /**
1169    * Returns whether the current document is a working copy owned by the current User
1170    *
1171    * @return true if the document is a working copy owner by the current User
1172    */

1173   public boolean isOwner()
1174   {
1175      return Repository.isNodeOwner(getDocument(), this.lockService);
1176   }
1177   
1178   /**
1179    * Returns the document this bean is currently representing
1180    *
1181    * @return The document Node
1182    */

1183   public Node getDocument()
1184   {
1185      return this.browseBean.getDocument();
1186   }
1187   
1188   /**
1189    * @return Returns the panels expanded state map.
1190    */

1191   public Map JavaDoc<String JavaDoc, Boolean JavaDoc> getPanels()
1192   {
1193      return this.panels;
1194   }
1195
1196   /**
1197    * @param panels The panels expanded state map.
1198    */

1199   public void setPanels(Map JavaDoc<String JavaDoc, Boolean JavaDoc> panels)
1200   {
1201      this.panels = panels;
1202   }
1203   
1204   /**
1205    * Sets the BrowseBean instance to use to retrieve the current document
1206    *
1207    * @param browseBean BrowseBean instance
1208    */

1209   public void setBrowseBean(BrowseBean browseBean)
1210   {
1211      this.browseBean = browseBean;
1212   }
1213
1214   /**
1215    * Sets the node service instance the bean should use
1216    *
1217    * @param nodeService The NodeService
1218    */

1219   public void setNodeService(NodeService nodeService)
1220   {
1221      this.nodeService = nodeService;
1222   }
1223
1224   /**
1225    * Sets the lock service instance the bean should use
1226    *
1227    * @param lockService The LockService
1228    */

1229   public void setLockService(LockService lockService)
1230   {
1231      this.lockService = lockService;
1232   }
1233
1234   /**
1235    * Sets the version service instance the bean should use
1236    *
1237    * @param versionService The VersionService
1238    */

1239   public void setVersionService(VersionService versionService)
1240   {
1241      this.versionService = versionService;
1242   }
1243   
1244   /**
1245    * Sets the copy service instance the bean should use
1246    *
1247    * @param copyService The CopyService
1248    */

1249   public void setCopyService(CopyService copyService)
1250   {
1251      this.copyService = copyService;
1252   }
1253   
1254   /**
1255    * Sets the ownable service instance the bean should use
1256    *
1257    * @param ownableService The OwnableService
1258    */

1259   public void setOwnableService(OwnableService ownableService)
1260   {
1261      this.ownableService = ownableService;
1262   }
1263   
1264   /**
1265    * @param navigator The NavigationBean to set.
1266    */

1267   public void setNavigator(NavigationBean navigator)
1268   {
1269      this.navigator = navigator;
1270   }
1271}
1272
Popular Tags