001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ui.apps.publishqueue;
029
030import org.opencms.db.CmsPublishList;
031import org.opencms.main.CmsException;
032import org.opencms.main.CmsLog;
033import org.opencms.main.OpenCms;
034import org.opencms.publish.CmsPublishJobBase;
035import org.opencms.publish.CmsPublishJobEnqueued;
036import org.opencms.publish.CmsPublishJobFinished;
037import org.opencms.publish.CmsPublishJobRunning;
038import org.opencms.security.CmsRole;
039import org.opencms.ui.A_CmsUI;
040import org.opencms.ui.CmsCssIcon;
041import org.opencms.ui.CmsVaadinUtils;
042import org.opencms.ui.apps.CmsAppWorkplaceUi;
043import org.opencms.ui.apps.Messages;
044import org.opencms.ui.components.CmsBasicDialog;
045import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
046import org.opencms.ui.components.OpenCmsTheme;
047import org.opencms.ui.contextmenu.CmsContextMenu;
048import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode;
049import org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry;
050import org.opencms.util.CmsStringUtil;
051import org.opencms.util.CmsUUID;
052
053import java.util.ArrayList;
054import java.util.Collections;
055import java.util.Date;
056import java.util.HashMap;
057import java.util.List;
058import java.util.Locale;
059import java.util.Map;
060import java.util.Set;
061
062import org.apache.commons.logging.Log;
063
064import com.vaadin.event.MouseEvents;
065import com.vaadin.server.Resource;
066import com.vaadin.shared.MouseEventDetails.MouseButton;
067import com.vaadin.ui.Button;
068import com.vaadin.ui.Window;
069import com.vaadin.ui.themes.ValoTheme;
070import com.vaadin.v7.data.util.BeanItemContainer;
071import com.vaadin.v7.data.util.filter.Or;
072import com.vaadin.v7.data.util.filter.SimpleStringFilter;
073import com.vaadin.v7.event.ItemClickEvent;
074import com.vaadin.v7.event.ItemClickEvent.ItemClickListener;
075import com.vaadin.v7.ui.Table;
076
077/**
078 * Class for Vaadin Table showing history queue elements.<p>
079 */
080public class CmsQueuedTable extends Table {
081
082    /**
083     * Row bean for the bean item container.
084     */
085    public class Row {
086
087        /** The underlying job. */
088        private CmsPublishJobBase m_job;
089
090        /** Cached list of resources. */
091        private List<?> m_resourceList;
092
093        /** The icon. */
094        private Resource m_icon;
095
096        /** Cached state. */
097        private String m_state;
098
099        /** Used for initial sorting. */
100        private int m_sortType;
101
102        /**
103         * Creates a new instance.
104         *
105         * @param job the underlying publish job
106         */
107        public Row(CmsPublishJobBase job, int sortType) {
108
109            m_job = job;
110            m_sortType = sortType;
111            if (job == null) {
112                throw new IllegalArgumentException("Job must not be null.");
113            }
114        }
115
116        /**
117         * Gets the file count.
118         *
119         * @return the file count
120         */
121        public int getFilesCount() {
122
123            return m_job.getSize();
124        }
125
126        /**
127         * Gets the icon.
128         *
129         * @return the icon
130         */
131        public Resource getIcon() {
132
133            if (m_icon == null) {
134                m_icon = new CmsCssIcon(OpenCmsTheme.ICON_PUBLISH);
135            }
136            return m_icon;
137        }
138
139        /**
140         * Gets the publish job.
141         *
142         * @return the publish job
143         */
144        public CmsPublishJobBase getJob() {
145
146            return m_job;
147        }
148
149        /**
150         * Gets the project name.
151         *
152         * @return the project name
153         */
154        public String getProject() {
155
156            return m_job.getProjectName().replace("&#47;", "/");
157        }
158
159        /**
160         * Gets the resource list.
161         *
162         * @return the resource list
163         */
164        public List<?> getResourceList() {
165
166            if (m_resourceList == null) {
167                if (m_job instanceof CmsPublishJobFinished) {
168                    try {
169                        m_resourceList = A_CmsUI.getCmsObject().readPublishedResources(m_job.getPublishHistoryId());
170                    } catch (Exception e) {
171                        LOG.error(e.getLocalizedMessage(), e);
172                    }
173                } else if (m_job instanceof CmsPublishJobEnqueued) {
174                    m_resourceList = ((CmsPublishJobEnqueued)m_job).getOriginalPublishList().getAllResources();
175                } else if (m_job instanceof CmsPublishJobRunning) {
176                    CmsPublishList publishList = ((CmsPublishJobRunning)m_job).getOriginalPublishList();
177                    if (publishList == null) {
178                        // publish job has already finished, can't get the publish list
179                        m_resourceList = Collections.emptyList();
180                    } else {
181                        m_resourceList = publishList.getAllResources();
182                    }
183                }
184            }
185            return m_resourceList;
186        }
187
188        /**
189         * Gets the resource list as a string.
190         *
191         * @return the resource list string representation
192         */
193        public String getResources() {
194
195            List<?> resources = getResourceList();
196            if (resources == null) {
197                return "";
198            }
199            return CmsResourcesCellGenerator.formatResourcesForTable(resources, 50);
200        }
201
202        /**
203         * Used for initial sorting.
204         *
205         * @return the sort type
206         */
207        public int getSortType() {
208
209            return m_sortType;
210        }
211
212        /**
213         * Gets the start date of the job.
214         *
215         * @return the start date
216         */
217        public Date getStart() {
218
219            if (m_job instanceof CmsPublishJobFinished) {
220                return new Date(((CmsPublishJobFinished)m_job).getStartTime());
221            } else if (m_job instanceof CmsPublishJobRunning) {
222                return new Date(((CmsPublishJobRunning)m_job).getStartTime());
223            }
224            return null;
225        }
226
227        /**
228         * Gets the job state.
229         *
230         * @return the job state
231         */
232        @SuppressWarnings("synthetic-access")
233        public String getStatus() {
234
235            if (m_state == null) {
236                if (m_job instanceof CmsPublishJobFinished) {
237                    m_state = getState((CmsPublishJobFinished)m_job);
238                } else if (m_job instanceof CmsPublishJobRunning) {
239                    m_state = STATE_RUNNING;
240                } else if (m_job instanceof CmsPublishJobEnqueued) {
241                    m_state = STATE_ENQUEUE;
242                } else {
243                    m_state = STATE_ERROR;
244                    LOG.error("Invalid job type: " + m_job);
245                }
246            }
247            return m_state;
248        }
249
250        /**
251         * Gets the user friendly label for the state.
252         *
253         * @return the user friendly state description
254         */
255        @SuppressWarnings("synthetic-access")
256        public String getStatusLocale() {
257
258            String state = getStatus();
259            String key = STATUS_MESSAGES.get(state);
260            if (key == null) {
261                LOG.error("KEY is null for state " + state);
262            }
263            return CmsVaadinUtils.getMessageText(key);
264        }
265
266        /**
267         * Gets the stop date for the job.
268         *
269         * @return the stop date
270         */
271        public Date getStop() {
272
273            if (m_job instanceof CmsPublishJobFinished) {
274                return new Date(((CmsPublishJobFinished)m_job).getFinishTime());
275            }
276            return null;
277        }
278
279        /**
280         * Gets the name of the user who started the job.
281         *
282         * @return the user name for the job
283         */
284        public String getUser() {
285
286            return m_job.getUserName(A_CmsUI.getCmsObject());
287        }
288
289    }
290
291    /**
292     *Menu entry for showing report.<p>
293     */
294    class EntryReport implements I_CmsSimpleContextMenuEntry<Set<String>>, I_CmsSimpleContextMenuEntry.I_HasCssStyles {
295
296        /**
297         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
298         */
299        public void executeAction(Set<String> data) {
300
301            showReportDialog(data.iterator().next());
302        }
303
304        /**
305         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry.I_HasCssStyles#getStyles()
306         */
307        public String getStyles() {
308
309            return ValoTheme.LABEL_BOLD;
310        }
311
312        /**
313         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
314         */
315        public String getTitle(Locale locale) {
316
317            return CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_REPORT_0);
318        }
319
320        /**
321         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
322         */
323        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
324
325            return (data != null) && (data.size() == 1)
326            ? CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE
327            : CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
328        }
329
330    }
331
332    /**
333     * Menu entry for showing resources.<p>
334     */
335    class EntryResources implements I_CmsSimpleContextMenuEntry<Set<String>> {
336
337        /**
338         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
339         */
340        public void executeAction(Set<String> data) {
341
342            showResourceDialog(data.iterator().next());
343
344        }
345
346        /**
347         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
348         */
349        public String getTitle(Locale locale) {
350
351            return CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_RESOURCES_0);
352        }
353
354        /**
355         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
356         */
357        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
358
359            return (data != null) && (data.size() == 1)
360            ? CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE
361            : CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
362        }
363    }
364
365    /**
366     * Menu entry for option to abort publish job.<p>
367     */
368    class EntryStop implements I_CmsSimpleContextMenuEntry<Set<String>>, I_CmsSimpleContextMenuEntry.I_HasCssStyles {
369
370        /**
371         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
372         */
373        public void executeAction(Set<String> data) {
374
375            String jobid = data.iterator().next();
376            CmsPublishJobBase job = OpenCms.getPublishManager().getJobByPublishHistoryId(new CmsUUID(jobid));
377            if (job instanceof CmsPublishJobEnqueued) {
378                try {
379                    OpenCms.getPublishManager().abortPublishJob(
380                        A_CmsUI.getCmsObject(),
381                        (CmsPublishJobEnqueued)job,
382                        true);
383                    CmsAppWorkplaceUi.get().reload();
384                } catch (CmsException e) {
385                    LOG.error("Error on aborting publish job.", e);
386                }
387            }
388        }
389
390        /**
391         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry.I_HasCssStyles#getStyles()
392         */
393        public String getStyles() {
394
395            return ValoTheme.LABEL_BOLD;
396        }
397
398        /**
399         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
400         */
401        public String getTitle(Locale locale) {
402
403            return CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_STOP_0);
404        }
405
406        /**
407         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
408         */
409        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
410
411            return (data != null) && (data.size() == 1)
412            ? CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE
413            : CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
414        }
415
416    }
417
418    /**Error status icon. */
419    public static final String ICON_ERROR = "apps/publishqueue/state_error.png";
420
421    /**Ok status icon. */
422    public static final String ICON_OK = "apps/publishqueue/state_ok.png";
423
424    /**Warning status icon. */
425    public static final String ICON_WARNINGS = "apps/publishqueue/state_warning.png";
426
427    /** list action id constant. */
428    public static final String LIST_ACTION_COUNT = "ac";
429
430    /** list action id constant. */
431    public static final String LIST_ACTION_END = "ae";
432
433    /** list action id constant. */
434    public static final String LIST_ACTION_PROJECT = "ap";
435
436    /** list action id constant. */
437    public static final String LIST_ACTION_START = "as";
438
439    /** list action id constant. */
440    public static final String LIST_ACTION_STATE_ERR = "ate";
441
442    /** list action id constant. */
443    public static final String LIST_ACTION_STATE_OK = "ato";
444
445    /** list action id constant. */
446    public static final String LIST_ACTION_VIEW = "av";
447
448    /** list id constant. */
449    public static final String LIST_ID = "lppq";
450
451    /** The logger for this class. */
452    static Log LOG = CmsLog.getLog(CmsQueuedTable.class.getName());
453
454    /**table column. */
455    private static final String PROP_FILESCOUNT = "filesCount";
456
457    /**table column. */
458    private static final String PROP_ICON = "icon";
459
460    /**table column. */
461    private static final String PROP_PROJECT = "project";
462
463    /**resources column.*/
464    private static final String PROP_RESOURCES = "resources";
465
466    /**table column. */
467    private static final String PROP_START = "start";
468
469    /**table column. */
470    private static final String PROP_STATUS = "status";
471
472    private static final String PROP_SORT_TYPE = "sortType";
473
474    /**table column. */
475    private static final String PROP_STATUS_LOCALE = "statusLocale";
476
477    /**table column. */
478    private static final String PROP_STOP = "stop";
479
480    /**table column. */
481    private static final String PROP_USER = "user";
482
483    /**vaadin serial id. */
484    private static final long serialVersionUID = 7507300060974348158L;
485
486    /** Publish job state constant. */
487    private static final String STATE_ERROR = "error";
488
489    /** Publish job state constant. */
490    private static final String STATE_OK = "ok";
491
492    /** Publish job state constant. */
493    private static final String STATE_WARNING = "warning";
494
495    /** Publish job state constant. */
496    private static final String STATE_RUNNING = "running";
497
498    /** Publish job state constant. */
499    private static final String STATE_ENQUEUE = "queue";
500
501    /** Publish job state constant. */
502    private static final Map<String, String> STATUS_MESSAGES = getStatusMap();
503
504    /**Container. */
505    BeanItemContainer<Row> m_container;
506
507    /**Instance of calling class.*/
508    CmsPublishQueue m_manager;
509
510    /** The context menu. */
511    CmsContextMenu m_menu;
512
513    /** The available menu entries. */
514    private List<I_CmsSimpleContextMenuEntry<Set<String>>> m_menuEntries;
515
516    /** The available menu entries. */
517    private List<I_CmsSimpleContextMenuEntry<Set<String>>> m_menuEntriesEnq;
518
519    /**
520     * Default constructor.<p>
521     *
522     * @param manager instance of calling class
523     */
524    public CmsQueuedTable(CmsPublishQueue manager) {
525
526        m_manager = manager;
527        setSizeFull();
528        setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_PQUEUE_HIST_0));
529
530        m_menu = new CmsContextMenu();
531        m_menu.setAsTableContextMenu(this);
532
533        m_container = new BeanItemContainer<Row>(Row.class);
534
535        setContainerDataSource(m_container);
536        //        setItemIconPropertyId(PROP_ICON);
537        //        setRowHeaderMode(RowHeaderMode.ICON_ONLY);
538        setColumnHeader(PROP_STATUS_LOCALE, "");
539        setColumnHeader(PROP_RESOURCES, CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_RESOURCES_0));
540        setColumnHeader(PROP_PROJECT, CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_PROJECT_0));
541        setColumnHeader(PROP_START, CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_STARTDATE_0));
542        setColumnHeader(PROP_STOP, CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_ENDDATE_0));
543        setColumnHeader(PROP_USER, CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_USER_0));
544        setColumnHeader(PROP_FILESCOUNT, CmsVaadinUtils.getMessageText(Messages.GUI_PQUEUE_SIZE_0));
545
546        setVisibleColumns(
547            PROP_STATUS_LOCALE,
548            PROP_PROJECT,
549            PROP_START,
550            PROP_STOP,
551            PROP_USER,
552            PROP_RESOURCES,
553            PROP_FILESCOUNT);
554        setColumnWidth(PROP_START, 200);
555        setColumnWidth(PROP_STOP, 200);
556        setColumnWidth(PROP_RESOURCES, 550);
557
558        setItemIconPropertyId(PROP_ICON);
559        setRowHeaderMode(RowHeaderMode.ICON_ONLY);
560        setColumnWidth(null, 40);
561
562        setSelectable(true);
563
564        addItemClickListener(new ItemClickListener() {
565
566            /**vaadin serial id. */
567            private static final long serialVersionUID = -7394790444104979594L;
568
569            public void itemClick(ItemClickEvent event) {
570
571                onItemClick(event, event.getItemId(), event.getPropertyId());
572
573            }
574
575        });
576
577        setCellStyleGenerator(new CellStyleGenerator() {
578
579            private static final long serialVersionUID = 1L;
580
581            public String getStyle(Table source, Object itemId, Object propertyId) {
582
583                if (PROP_RESOURCES.equals(propertyId)) {
584                    return " " + OpenCmsTheme.HOVER_COLUMN;
585                }
586
587                if (PROP_PROJECT.equals(propertyId) & !(itemId instanceof CmsPublishJobEnqueued)) {
588                    return " " + OpenCmsTheme.HOVER_COLUMN;
589                }
590
591                if (PROP_STATUS_LOCALE.equals(propertyId)) {
592                    if (STATE_OK.equals(source.getItem(itemId).getItemProperty(PROP_STATUS).getValue())) {
593                        return OpenCmsTheme.TABLE_COLUMN_BOX_GREEN;
594                    }
595                    if (STATE_WARNING.equals(source.getItem(itemId).getItemProperty(PROP_STATUS).getValue())) {
596                        return OpenCmsTheme.TABLE_COLUMN_BOX_ORANGE;
597                    }
598                    if (STATE_ERROR.equals(source.getItem(itemId).getItemProperty(PROP_STATUS).getValue())) {
599                        return OpenCmsTheme.TABLE_COLUMN_BOX_RED;
600                    }
601                    if (STATE_RUNNING.equals(source.getItem(itemId).getItemProperty(PROP_STATUS).getValue())) {
602                        return OpenCmsTheme.TABLE_COLUMN_BOX_DARKGRAY;
603                    }
604                    if (STATE_ENQUEUE.equals(source.getItem(itemId).getItemProperty(PROP_STATUS).getValue())) {
605                        return OpenCmsTheme.TABLE_COLUMN_BOX_GRAY;
606                    }
607                }
608
609                return null;
610            }
611        });
612
613        // addGeneratedColumn(PROP_RESOURCES, new CmsResourcesCellGenerator(50));
614        loadJobs();
615    }
616
617    /**
618     * Returns the status message map.<p>
619     *
620     * @return the status message map
621     */
622    private static Map<String, String> getStatusMap() {
623
624        Map<String, String> map = new HashMap<String, String>();
625        map.put(STATE_OK, Messages.GUI_PQUEUE_STATUS_OK_0);
626        map.put(STATE_WARNING, Messages.GUI_PQUEUE_STATUS_WARNING_0);
627        map.put(STATE_ERROR, Messages.GUI_PQUEUE_STATUS_ERROR_0);
628        map.put(STATE_RUNNING, Messages.GUI_PQUEUE_STATUS_RUNNING_0);
629        map.put(STATE_ENQUEUE, Messages.GUI_PQUEUE_STATUS_ENQUEUE_0);
630
631        return map;
632    }
633
634    /**
635     * Filters the table according to given search string.<p>
636     *
637     * @param search string to be looked for.
638     */
639    public void filterTable(String search) {
640
641        m_container.removeAllContainerFilters();
642        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(search)) {
643            m_container.addContainerFilter(
644                new Or(
645                    new SimpleStringFilter(PROP_USER, search, true, false),
646                    new SimpleStringFilter(PROP_RESOURCES, search, true, false),
647                    new SimpleStringFilter(PROP_PROJECT, search, true, false)));
648        }
649    }
650
651    /**
652     * Show report dialog.<p>
653     *
654     * @param jobid to show report for
655     */
656    protected void showReportDialog(String jobid) {
657
658        CmsPublishReport pReport = new CmsPublishReport(jobid);
659        final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide);
660        CmsBasicDialog dialog = new CmsBasicDialog();
661        dialog.addButton(
662            new Button(
663                CmsVaadinUtils.getMessageText(org.opencms.workplace.Messages.GUI_DIALOG_BUTTON_CLOSE_0),
664                new com.vaadin.ui.Button.ClickListener() {
665
666                    private static final long serialVersionUID = -4216949392648631634L;
667
668                    public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
669
670                        window.close();
671
672                    }
673                }),
674            true);
675        dialog.setContent(pReport);
676        window.setContent(dialog);
677        window.setCaption(pReport.getCaption());
678        A_CmsUI.get().addWindow(window);
679    }
680
681    /**
682     * Show resource dialog.<p>
683     *
684     * @param jobid to show resources for
685     */
686    protected void showResourceDialog(String jobid) {
687
688        CmsPublishResources pResources = new CmsPublishResources(jobid);
689        final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide);
690        CmsBasicDialog dialog = new CmsBasicDialog();
691        dialog.addButton(
692            new Button(
693                CmsVaadinUtils.getMessageText(org.opencms.workplace.Messages.GUI_DIALOG_BUTTON_CLOSE_0),
694                new com.vaadin.ui.Button.ClickListener() {
695
696                    private static final long serialVersionUID = -4216949392648631634L;
697
698                    public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
699
700                        window.close();
701
702                    }
703                }),
704            true);
705        dialog.setContent(pResources);
706        window.setContent(dialog);
707        window.setCaption(pResources.getCaption());
708        A_CmsUI.get().addWindow(window);
709    }
710
711    /**
712     * Returns the available menu entries.<p>
713     *
714     * @return the menu entries
715     */
716    List<I_CmsSimpleContextMenuEntry<Set<String>>> getMenuEntries() {
717
718        if (getValue() instanceof CmsPublishJobEnqueued) {
719            if (m_menuEntriesEnq == null) {
720                m_menuEntriesEnq = new ArrayList<I_CmsSimpleContextMenuEntry<Set<String>>>();
721                m_menuEntriesEnq.add(new EntryStop());
722                m_menuEntriesEnq.add(new EntryResources());
723            }
724            return m_menuEntriesEnq;
725        }
726
727        if (m_menuEntries == null) {
728            m_menuEntries = new ArrayList<I_CmsSimpleContextMenuEntry<Set<String>>>();
729            m_menuEntries.add(new EntryReport());
730            m_menuEntries.add(new EntryResources());
731        }
732        return m_menuEntries;
733    }
734
735    /**
736     * Handles the table item clicks, including clicks on images inside of a table item.<p>
737     *
738     * @param event the click event
739     * @param itemId of the clicked row
740     * @param propertyId column id
741     */
742    void onItemClick(MouseEvents.ClickEvent event, Object itemId, Object propertyId) {
743
744        setValue(null);
745        select(itemId);
746        if (event.getButton().equals(MouseButton.RIGHT) || (propertyId == null)) {
747            m_menu.setEntries(
748                getMenuEntries(),
749                Collections.singleton(((((Row)getValue()).getJob()).getPublishHistoryId()).getStringValue()));
750            m_menu.openForTable(event, itemId, propertyId, CmsQueuedTable.this);
751        } else if (event.getButton().equals(MouseButton.LEFT) && PROP_RESOURCES.equals(propertyId)) {
752            showResourceDialog((((Row)getValue()).getJob()).getPublishHistoryId().getStringValue());
753        } else if (event.getButton().equals(MouseButton.LEFT) && PROP_PROJECT.equals(propertyId)) {
754            if (!(getValue() instanceof CmsPublishJobEnqueued)) {
755                showReportDialog(((((Row)getValue()).getJob()).getPublishHistoryId().getStringValue()));
756            }
757        }
758    }
759
760    /**
761     * Returns the state of the given publish job.<p>
762     *
763     * @param publishJob the publish job to get the state for
764     * @return the state of the given publish job
765     */
766    private String getState(CmsPublishJobFinished publishJob) {
767
768        byte[] reportBytes = null;
769        try {
770            reportBytes = OpenCms.getPublishManager().getReportContents(publishJob);
771        } catch (CmsException e) {
772            //Can't read report -> error
773            return STATE_ERROR;
774        }
775        if (reportBytes != null) {
776            String report = new String(reportBytes);
777            if (report.indexOf("<span class='err'>") > -1) {
778                //Report contains error span
779                return STATE_ERROR;
780
781            }
782            if (report.indexOf("<span class='warn'>") > -1) {
783                //Report contains warning span
784                return STATE_WARNING;
785
786            }
787        }
788        //no warning or error state detected -> ok
789        return STATE_OK;
790
791    }
792
793    /**
794     * Fills the table with finished publish jobs.<p>
795     */
796    private void loadJobs() {
797
798        List<CmsPublishJobFinished> publishJobs;
799        if (OpenCms.getRoleManager().hasRole(A_CmsUI.getCmsObject(), CmsRole.ROOT_ADMIN)) {
800            publishJobs = OpenCms.getPublishManager().getPublishHistory();
801        } else {
802            publishJobs = OpenCms.getPublishManager().getPublishHistory(
803                A_CmsUI.getCmsObject().getRequestContext().getCurrentUser());
804        }
805        for (CmsPublishJobFinished job : publishJobs) {
806            m_container.addBean(new Row(job, 0));
807        }
808        //Sort table according to start time of jobs
809        m_container.sort(new String[] {PROP_START}, new boolean[] {false});
810
811        List<CmsPublishJobBase> jobs = new ArrayList<CmsPublishJobBase>();
812
813        //a) running jobs
814        if (OpenCms.getPublishManager().isRunning()) {
815            CmsPublishJobRunning currentJob = OpenCms.getPublishManager().getCurrentPublishJob();
816            if (currentJob != null) {
817                m_container.addBean(new Row(currentJob, 1));
818            }
819        }
820
821        int i = 0;
822        for (CmsPublishJobBase job : OpenCms.getPublishManager().getPublishQueue()) {
823            m_container.addBean(new Row(job, 2 + i));
824            i += 1;
825        }
826        m_container.sort(new String[] {PROP_SORT_TYPE, PROP_START}, new boolean[] {false, false});
827
828    }
829}