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.projects;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.main.CmsException;
033import org.opencms.main.CmsLog;
034import org.opencms.main.OpenCms;
035import org.opencms.security.CmsRole;
036import org.opencms.ui.A_CmsUI;
037import org.opencms.ui.CmsVaadinUtils;
038import org.opencms.ui.FontOpenCms;
039import org.opencms.ui.I_CmsDialogContext;
040import org.opencms.ui.I_CmsDialogContext.ContextType;
041import org.opencms.ui.apps.A_CmsWorkplaceApp;
042import org.opencms.ui.apps.CmsFileExplorer;
043import org.opencms.ui.apps.I_CmsContextProvider;
044import org.opencms.ui.apps.Messages;
045import org.opencms.ui.components.CmsBasicDialog;
046import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
047import org.opencms.ui.components.CmsErrorDialog;
048import org.opencms.ui.components.CmsFileTable;
049import org.opencms.ui.components.CmsFileTableDialogContext;
050import org.opencms.ui.components.CmsInfoButton;
051import org.opencms.ui.components.CmsToolBar;
052import org.opencms.util.CmsStringUtil;
053import org.opencms.util.CmsUUID;
054
055import java.util.ArrayList;
056import java.util.LinkedHashMap;
057import java.util.List;
058import java.util.Map;
059
060import org.apache.commons.logging.Log;
061
062import com.vaadin.v7.event.FieldEvents.TextChangeEvent;
063import com.vaadin.v7.event.FieldEvents.TextChangeListener;
064import com.vaadin.ui.Button;
065import com.vaadin.ui.Button.ClickEvent;
066import com.vaadin.ui.Button.ClickListener;
067import com.vaadin.ui.Component;
068import com.vaadin.v7.ui.TextField;
069import com.vaadin.ui.UI;
070import com.vaadin.ui.Window;
071import com.vaadin.ui.themes.ValoTheme;
072
073/**
074 * The project manager app.<p>
075 */
076public class CmsProjectManager extends A_CmsWorkplaceApp {
077
078    /** The project files path name. */
079    public static final String PATH_NAME_FILES = "files";
080
081    /** The project history path name. */
082    public static final String PATH_NAME_HISTORY = "history";
083
084    /** The logger for this class. */
085    private static Log LOG = CmsLog.getLog(CmsProjectManager.class.getName());
086
087    /** The projects table. */
088    CmsProjectsTable m_projectsTable;
089
090    /** The file table filter input. */
091    private TextField m_fileTableFilter;
092
093    /** The sub nav buttons of this app. */
094    private List<Component> m_navButtons = new ArrayList<Component>();
095
096    /** The project table filter input. */
097    private TextField m_projectTableFilter;
098
099    /**
100     * Returns the projects table component.<p>
101     *
102     * @return the projects table
103     */
104    protected CmsProjectsTable createProjectsTable() {
105
106        CmsProjectsTable table = new CmsProjectsTable(this);
107        table.loadProjects();
108        return table;
109    }
110
111    /**
112     * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getBreadCrumbForState(java.lang.String)
113     */
114    @Override
115    protected LinkedHashMap<String, String> getBreadCrumbForState(String state) {
116
117        LinkedHashMap<String, String> crumbs = new LinkedHashMap<String, String>();
118        if (!OpenCms.getRoleManager().hasRole(A_CmsUI.getCmsObject(), CmsRole.PROJECT_MANAGER)) {
119            crumbs.put(
120                "",
121                CmsVaadinUtils.getMessageText(
122                    Messages.GUI_PROJECTS_FILES_1,
123                    A_CmsUI.getCmsObject().getRequestContext().getCurrentProject().getName()));
124        } else if (CmsStringUtil.isEmptyOrWhitespaceOnly(state)) {
125            crumbs.put("", CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_0));
126        } else if (state.equals(PATH_NAME_HISTORY)) {
127            crumbs.put(CmsProjectManagerConfiguration.APP_ID, CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_0));
128            crumbs.put("", CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_HISTORY_0));
129        } else if (state.startsWith(PATH_NAME_FILES)) {
130            CmsUUID projectId = getIdFromState(state);
131            if (projectId != null) {
132                crumbs.put(
133                    CmsProjectManagerConfiguration.APP_ID,
134                    CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_0));
135                try {
136                    crumbs.put(
137                        "",
138                        CmsVaadinUtils.getMessageText(
139                            Messages.GUI_PROJECTS_FILES_1,
140                            A_CmsUI.getCmsObject().readProject(projectId).getName()));
141                } catch (CmsException e) {
142                    LOG.error("Error reading project for bread crumb.", e);
143                }
144            }
145        }
146        return crumbs;
147    }
148
149    /**
150     * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getComponentForState(java.lang.String)
151     */
152    @Override
153    protected Component getComponentForState(String state) {
154
155        if (!OpenCms.getRoleManager().hasRole(A_CmsUI.getCmsObject(), CmsRole.PROJECT_MANAGER)) {
156            return prepareProjectFilesTable(A_CmsUI.getCmsObject().getRequestContext().getCurrentProject().getUuid());
157        } else {
158
159            if (m_fileTableFilter != null) {
160                m_infoLayout.removeComponent(m_fileTableFilter);
161                m_fileTableFilter = null;
162            }
163            if (m_projectTableFilter != null) {
164                m_infoLayout.removeComponent(m_projectTableFilter);
165                m_projectTableFilter = null;
166            }
167
168            if (CmsStringUtil.isEmptyOrWhitespaceOnly(state)) {
169                m_rootLayout.setMainHeightFull(true);
170                if (m_projectsTable == null) {
171                    m_projectsTable = createProjectsTable();
172                } else {
173                    m_projectsTable.loadProjects();
174                }
175                m_projectTableFilter = new TextField();
176                m_projectTableFilter.setIcon(FontOpenCms.FILTER);
177                m_projectTableFilter.setInputPrompt(
178                    Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_FILTER_0));
179                m_projectTableFilter.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON);
180                m_projectTableFilter.setWidth("200px");
181                m_projectTableFilter.addTextChangeListener(new TextChangeListener() {
182
183                    private static final long serialVersionUID = 1L;
184
185                    public void textChange(TextChangeEvent event) {
186
187                        m_projectsTable.filterTable(event.getText());
188
189                    }
190                });
191                m_infoLayout.addComponent(m_projectTableFilter);
192                showNavButtons();
193                return m_projectsTable;
194                //            } else if (state.equals(PATH_NAME_ADD)) {
195                //                m_rootLayout.setMainHeightFull(false);
196                //                return getNewProjectForm();
197            } else if (state.equals(PATH_NAME_HISTORY)) {
198                m_rootLayout.setMainHeightFull(true);
199                hideNavButtons();
200                return new CmsProjectHistoryTable();
201                //            } else if (state.startsWith(PATH_NAME_EDIT)) {
202                //                CmsUUID projectId = getIdFromState(state);
203                //                if (projectId != null) {
204                //                    m_rootLayout.setMainHeightFull(false);
205                //                    return new CmsEditProjectForm(this, projectId);
206                //                }
207            } else if (state.startsWith(PATH_NAME_FILES)) {
208                hideNavButtons();
209                CmsUUID projectId = getIdFromState(state);
210                if (projectId != null) {
211                    return prepareProjectFilesTable(projectId);
212                }
213            }
214        }
215        return null;
216    }
217
218    /**
219     * Returns the project files table.<p>
220     *
221     * @param projectId the selected project id
222     *
223     * @return the file table
224     */
225    protected CmsFileTable getProjectFiles(CmsUUID projectId) {
226
227        final CmsFileTable fileTable = new CmsFileTable(null);
228        fileTable.applyWorkplaceAppSettings();
229        fileTable.setContextProvider(new I_CmsContextProvider() {
230
231            /**
232             * @see org.opencms.ui.apps.I_CmsContextProvider#getDialogContext()
233             */
234            public I_CmsDialogContext getDialogContext() {
235
236                CmsFileTableDialogContext context = new CmsFileTableDialogContext(
237                    CmsProjectManagerConfiguration.APP_ID,
238                    ContextType.fileTable,
239                    fileTable,
240                    fileTable.getSelectedResources());
241                context.setEditableProperties(CmsFileExplorer.INLINE_EDIT_PROPERTIES);
242                return context;
243            }
244        });
245        CmsObject cms = A_CmsUI.getCmsObject();
246        List<CmsResource> childResources;
247        try {
248            childResources = cms.readProjectView(projectId, CmsResource.STATE_KEEP);
249            fileTable.fillTable(cms, childResources);
250        } catch (CmsException e) {
251            CmsErrorDialog.showErrorDialog(
252                CmsVaadinUtils.getMessageText(Messages.ERR_PROJECTS_CAN_NOT_DISPLAY_FILES_0),
253                e);
254        }
255        return fileTable;
256    }
257
258    //    /**
259    //     * Returns the new project form component.<p>
260    //     *
261    //     * @return the form component
262    //     */
263    //    protected Component getNewProjectForm() {
264    //
265    //        return new CmsEditProjectForm(this);
266    //    }
267
268    /**
269     * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getSubNavEntries(java.lang.String)
270     */
271    @Override
272    protected List<NavEntry> getSubNavEntries(String state) {
273
274        return null;
275    }
276
277    /**
278     * Returns the project id parameter from the given state.<p>
279     *
280     * @param state the state
281     *
282     * @return the project id
283     */
284    private CmsUUID getIdFromState(String state) {
285
286        CmsUUID result = null;
287        String temp = A_CmsWorkplaceApp.getParamFromState(state, "projectId");
288        if (CmsUUID.isValidUUID(temp)) {
289            result = new CmsUUID(temp);
290        }
291        return result;
292    }
293
294    /**
295     * Hides the sub navigation buttons.<p>
296     */
297    private void hideNavButtons() {
298
299        for (Component button : m_navButtons) {
300            button.setVisible(false);
301        }
302    }
303
304    /**
305     * Prepares the view to show the project files table.<p>
306     *
307     * @param projectId the project id
308     *
309     * @return the project file table
310     */
311    private CmsFileTable prepareProjectFilesTable(CmsUUID projectId) {
312
313        m_rootLayout.setMainHeightFull(true);
314        final CmsFileTable fileTable = getProjectFiles(projectId);
315        m_fileTableFilter = new TextField();
316        m_fileTableFilter.setIcon(FontOpenCms.FILTER);
317        m_fileTableFilter.setInputPrompt(
318            Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_FILTER_0));
319        m_fileTableFilter.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON);
320        m_fileTableFilter.setWidth("200px");
321        m_fileTableFilter.addTextChangeListener(new TextChangeListener() {
322
323            private static final long serialVersionUID = 1L;
324
325            public void textChange(TextChangeEvent event) {
326
327                fileTable.filterTable(event.getText());
328
329            }
330        });
331        m_infoLayout.addComponent(m_fileTableFilter);
332        return fileTable;
333    }
334
335    /**
336     * Shows the sub navigation buttons.<p>
337     */
338    private void showNavButtons() {
339
340        if (m_navButtons.isEmpty()) {
341            Button addProject = CmsToolBar.createButton(
342                FontOpenCms.WAND,
343                CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_ADD_0));
344            addProject.addClickListener(new ClickListener() {
345
346                private static final long serialVersionUID = 1L;
347
348                public void buttonClick(ClickEvent event) {
349
350                    Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide);
351                    CmsEditProjectForm form = new CmsEditProjectForm(m_projectsTable, window);
352                    window.setContent(form);
353                    window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_ADD_0));
354                    A_CmsUI.get().addWindow(window);
355                    window.center();
356                }
357            });
358            m_uiContext.addToolbarButton(addProject);
359            m_navButtons.add(addProject);
360            Button history = CmsToolBar.createButton(
361                FontOpenCms.CLIPBOARD,
362                CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_HISTORY_0));
363            history.addClickListener(new ClickListener() {
364
365                private static final long serialVersionUID = 1L;
366
367                public void buttonClick(ClickEvent event) {
368
369                    openSubView(CmsProjectManager.PATH_NAME_HISTORY, true);
370                }
371            });
372            m_uiContext.addToolbarButton(history);
373            m_navButtons.add(history);
374            try {
375                Map<String, String> infos = new LinkedHashMap<String, String>();
376                infos.put(
377                    CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_STATISTICS_COUNT_0),
378                    String.valueOf(
379                        OpenCms.getOrgUnitManager().getAllManageableProjects(A_CmsUI.getCmsObject(), "", true).size()));
380                CmsInfoButton infoButton = new CmsInfoButton(infos);
381                infoButton.setWindowCaption(CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_STATISTICS_0));
382                infoButton.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_STATISTICS_0));
383                m_uiContext.addToolbarButton(infoButton);
384            } catch (CmsException e) {
385                LOG.error("unable to get orgunit manager", e);
386            }
387        } else {
388            for (Component button : m_navButtons) {
389                button.setVisible(true);
390            }
391        }
392    }
393}