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.cacheadmin;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.file.types.CmsResourceTypeImage;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.main.OpenCms;
036import org.opencms.ui.A_CmsUI;
037import org.opencms.ui.CmsVaadinUtils;
038import org.opencms.ui.apps.A_CmsWorkplaceApp;
039import org.opencms.ui.apps.CmsAppWorkplaceUi;
040import org.opencms.ui.apps.CmsFileExplorerConfiguration;
041import org.opencms.ui.apps.Messages;
042import org.opencms.ui.apps.cacheadmin.CmsCacheViewApp.Mode;
043import org.opencms.ui.components.CmsBasicDialog;
044import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
045import org.opencms.ui.components.OpenCmsTheme;
046import org.opencms.ui.contextmenu.CmsContextMenu;
047import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode;
048import org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry;
049import org.opencms.util.CmsStringUtil;
050import org.opencms.workplace.explorer.CmsResourceUtil;
051
052import java.util.ArrayList;
053import java.util.Collection;
054import java.util.Collections;
055import java.util.List;
056import java.util.Locale;
057import java.util.Set;
058
059import org.apache.commons.logging.Log;
060
061import com.vaadin.server.Resource;
062import com.vaadin.shared.MouseEventDetails.MouseButton;
063import com.vaadin.ui.Window;
064import com.vaadin.ui.themes.ValoTheme;
065import com.vaadin.v7.data.Item;
066import com.vaadin.v7.data.util.IndexedContainer;
067import com.vaadin.v7.data.util.filter.Or;
068import com.vaadin.v7.data.util.filter.SimpleStringFilter;
069import com.vaadin.v7.event.ItemClickEvent;
070import com.vaadin.v7.event.ItemClickEvent.ItemClickListener;
071import com.vaadin.v7.ui.Table;
072import com.vaadin.v7.ui.TextField;
073import com.vaadin.v7.ui.VerticalLayout;
074
075/**
076 * Table to show entries of image cache.<p>
077 */
078public class CmsImageCacheTable extends Table {
079
080    /**
081     * Menu entry for show variations option.<p>
082     */
083    class EntryVariations
084    implements I_CmsSimpleContextMenuEntry<Set<String>>, I_CmsSimpleContextMenuEntry.I_HasCssStyles {
085
086        /**
087         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
088         */
089        public void executeAction(Set<String> data) {
090
091            String resource = data.iterator().next();
092            showVariationsWindow(resource);
093        }
094
095        /**
096         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry.I_HasCssStyles#getStyles()
097         */
098        public String getStyles() {
099
100            return ValoTheme.LABEL_BOLD;
101        }
102
103        /**
104         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
105         */
106        public String getTitle(Locale locale) {
107
108            return CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEXCACHE_LABEL_STATS_VARIATIONS_0);
109        }
110
111        /**
112         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
113         */
114        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
115
116            return (data != null) && (data.size() == 1)
117            ? CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE
118            : CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
119        }
120    }
121
122    /**
123     * The menu entry to switch to the explorer of concerning site.<p>
124     */
125    class ExplorerEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
126
127        /**
128         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
129         */
130        public void executeAction(Set<String> data) {
131
132            CmsResource res;
133            try {
134                res = getRootCms().readResource(data.iterator().next());
135                openExplorerForParent(res.getRootPath(), res.getStructureId().getStringValue());
136            } catch (CmsException e) {
137                e.printStackTrace();
138            }
139
140        }
141
142        /**
143         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
144         */
145        public String getTitle(Locale locale) {
146
147            return Messages.get().getBundle(locale).key(Messages.GUI_EXPLORER_TITLE_0);
148        }
149
150        /**
151         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
152         */
153        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
154
155            if (data == null) {
156                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
157            }
158
159            String res = data.iterator().next();
160
161            if (!A_CmsUI.getCmsObject().getRequestContext().getSiteRoot().equals("")) {
162                if (!res.startsWith(A_CmsUI.getCmsObject().getRequestContext().getSiteRoot())) {
163                    return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
164                }
165            }
166
167            return data.size() == 1
168            ? CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE
169            : CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
170        }
171
172    }
173
174    /**
175     * Column for dimensions of image.<p>
176     */
177    class VariationsColumn implements Table.ColumnGenerator {
178
179        /**vaadin serial id.*/
180        private static final long serialVersionUID = -4569513960107614645L;
181
182        /**
183         * @see com.vaadin.ui.Table.ColumnGenerator#generateCell(com.vaadin.ui.Table, java.lang.Object, java.lang.Object)
184         */
185        public Object generateCell(Table source, Object itemId, Object columnId) {
186
187            return Integer.valueOf(HELPER.getVariationsCount((String)itemId));
188        }
189
190    }
191
192    /**Image cache helper instance. */
193    protected static CmsImageCacheHolder HELPER;
194
195    /** The logger for this class. */
196    static Log LOG = CmsLog.getLog(CmsImageCacheTable.class.getName());
197
198    /**Column for icon.*/
199    private static final String PROP_ICON = "icon";
200
201    /**column for name of image.*/
202    private static final String PROP_NAME = "name";
203
204    /**column for image dimension.*/
205    private static final String PROP_VARIATIONS = "variations";
206
207    /**vaadin serial id.*/
208    private static final long serialVersionUID = -5559186186646954045L;
209
210    /** The context menu. */
211    CmsContextMenu m_menu;
212
213    /**Indexed container.*/
214    private IndexedContainer m_container;
215
216    /**intro result view.*/
217    private VerticalLayout m_intro;
218
219    /** The available menu entries. */
220    private List<I_CmsSimpleContextMenuEntry<Set<String>>> m_menuEntries;
221
222    /**null result view. */
223    private VerticalLayout m_nullResult;
224
225    /**CmsObject at root.*/
226    private CmsObject m_rootCms;
227
228    /**Filter text field for table. */
229    private TextField m_siteTableFilter;
230
231    /**
232     * public constructor.<p>
233     * @param nullResult vaadin component
234     * @param intro vaadin component
235     * @param siteTableFilter vaadin component
236     */
237    public CmsImageCacheTable(VerticalLayout intro, VerticalLayout nullResult, TextField siteTableFilter) {
238
239        m_intro = intro;
240        m_nullResult = nullResult;
241        m_siteTableFilter = siteTableFilter;
242
243        //Set menu
244        m_menu = new CmsContextMenu();
245        m_menu.setAsTableContextMenu(this);
246
247        //Setup container, sortable only for Name because other properties are loaded in background
248        m_container = new IndexedContainer() {
249
250            private static final long serialVersionUID = -8679153149897733835L;
251
252            @Override
253            public Collection<?> getSortableContainerPropertyIds() {
254
255                return Collections.singleton(PROP_NAME);
256            }
257        };
258
259        m_container.addContainerProperty(
260            PROP_ICON,
261            Resource.class,
262            CmsResourceUtil.getBigIconResource(
263                OpenCms.getWorkplaceManager().getExplorerTypeSetting(CmsResourceTypeImage.getStaticTypeName()),
264                null));
265        m_container.addContainerProperty(PROP_NAME, String.class, "");
266        m_container.addContainerProperty(PROP_VARIATIONS, Integer.class, "");
267        //ini Table
268        setContainerDataSource(m_container);
269        setColumnHeader(PROP_NAME, CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_IMAGECACHE_LIST_COLS_RESOURCE_0));
270        setColumnHeader(
271            PROP_VARIATIONS,
272            CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_IMAGECACHE_LIST_COLS_VARIATIONS_0));
273
274        setItemIconPropertyId(PROP_ICON);
275        setRowHeaderMode(RowHeaderMode.ICON_ONLY);
276
277        setColumnWidth(null, 40);
278
279        setSelectable(true);
280
281        addGeneratedColumn(PROP_VARIATIONS, new VariationsColumn());
282
283        addItemClickListener(new ItemClickListener() {
284
285            private static final long serialVersionUID = -4738296706762013443L;
286
287            public void itemClick(ItemClickEvent event) {
288
289                setValue(null);
290                select(event.getItemId());
291
292                //Right click or click on icon column (=null) -> show menu
293                if (event.getButton().equals(MouseButton.RIGHT) || (event.getPropertyId() == null)) {
294                    m_menu.setEntries(getMenuEntries(), Collections.singleton((String)getValue()));
295                    m_menu.openForTable(event, event.getItemId(), event.getPropertyId(), CmsImageCacheTable.this);
296                }
297
298                if (event.getButton().equals(MouseButton.LEFT) & PROP_NAME.equals(event.getPropertyId())) {
299                    showVariationsWindow(((String)getValue()));
300                }
301            }
302        });
303
304        setCellStyleGenerator(new CellStyleGenerator() {
305
306            private static final long serialVersionUID = 1L;
307
308            public String getStyle(Table source, Object itemId, Object propertyId) {
309
310                if (PROP_NAME.equals(propertyId)) {
311                    return " " + OpenCmsTheme.HOVER_COLUMN;
312                }
313
314                return null;
315            }
316        });
317
318        setColumnWidth(PROP_VARIATIONS, 100);
319
320    }
321
322    /**
323     * Filters the table according to given search string.<p>
324     *
325     * @param search string to be looked for.
326     */
327    public void filterTable(String search) {
328
329        m_container.removeAllContainerFilters();
330        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(search)) {
331            m_container.addContainerFilter(new Or(new SimpleStringFilter(PROP_NAME, search, true, false)));
332        }
333        if ((getValue() != null)) {
334            setCurrentPageFirstItemId(getValue());
335        }
336    }
337
338    /**
339     * Loads the table.<p>
340     *
341     * @param search searchstring to be considered
342     */
343    public void load(String search) {
344
345        HELPER = new CmsImageCacheHolder(search);
346        loadTable();
347    }
348
349    /**
350     * Returns the available menu entries.<p>
351     *
352     * @return the menu entries
353     */
354    List<I_CmsSimpleContextMenuEntry<Set<String>>> getMenuEntries() {
355
356        if (m_menuEntries == null) {
357            m_menuEntries = new ArrayList<I_CmsSimpleContextMenuEntry<Set<String>>>();
358            m_menuEntries.add(new EntryVariations()); //Option for Variations
359            m_menuEntries.add(new ExplorerEntry());
360        }
361        return m_menuEntries;
362    }
363
364    /**
365     * Returns a cms object at root-site.<p>
366     *
367     * @return cmsobject
368     */
369    CmsObject getRootCms() {
370
371        try {
372            if (m_rootCms == null) {
373
374                m_rootCms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
375                m_rootCms.getRequestContext().setSiteRoot("");
376            }
377        } catch (CmsException e) {
378            //
379        }
380        return m_rootCms;
381
382    }
383
384    /**
385     * Opens the explorer for given path and selected resource.<p>
386     *
387     * @param rootPath to be opened
388     * @param uuid to be selected
389     */
390    void openExplorerForParent(String rootPath, String uuid) {
391
392        String parentPath = CmsResource.getParentFolder(rootPath);
393        CmsAppWorkplaceUi.get().showApp(
394            CmsFileExplorerConfiguration.APP_ID,
395            A_CmsUI.getCmsObject().getRequestContext().getCurrentProject().getUuid()
396                + A_CmsWorkplaceApp.PARAM_SEPARATOR
397                + A_CmsUI.getCmsObject().getRequestContext().getSiteRoot()
398                + A_CmsWorkplaceApp.PARAM_SEPARATOR
399                + parentPath.substring(A_CmsUI.getCmsObject().getRequestContext().getSiteRoot().length())
400                + A_CmsWorkplaceApp.PARAM_SEPARATOR
401                + uuid
402                + A_CmsWorkplaceApp.PARAM_SEPARATOR);
403    }
404
405    /**
406     * Shows dialog for variations of given resource.<p>
407     *
408     * @param resource to show variations for
409     */
410    void showVariationsWindow(String resource) {
411
412        final Window window = CmsBasicDialog.prepareWindow(DialogWidth.max);
413        CmsVariationsDialog variationsDialog = new CmsVariationsDialog(resource, new Runnable() {
414
415            public void run() {
416
417                window.close();
418
419            }
420
421        }, Mode.ImageCache);
422        try {
423            CmsResource resourceObject = getRootCms().readResource(resource);
424            variationsDialog.displayResourceInfo(Collections.singletonList(resourceObject));
425        } catch (CmsException e) {
426            //
427        }
428        window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_VIEW_FLEX_VARIATIONS_1, resource));
429        window.setContent(variationsDialog);
430        A_CmsUI.get().addWindow(window);
431        window.center();
432    }
433
434    /**
435     * Fills table with entries from image cache helper.<p>
436     */
437    private void loadTable() {
438
439        m_nullResult.setVisible(false);
440        m_intro.setVisible(false);
441        setVisible(true);
442        m_siteTableFilter.setVisible(true);
443
444        m_container.removeAllItems();
445
446        setVisibleColumns(PROP_NAME, PROP_VARIATIONS);
447
448        List<String> resources = HELPER.getAllCachedImages();
449
450        for (String res : resources) {
451            Item item = m_container.addItem(res);
452            item.getItemProperty(PROP_NAME).setValue(res);
453        }
454
455        if (resources.size() == 0) {
456            m_nullResult.setVisible(true);
457            setVisible(false);
458            m_siteTableFilter.setVisible(false);
459        }
460
461    }
462
463}