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.xml.containerpage;
029
030import org.opencms.util.CmsCollectionsGenericWrapper;
031import org.opencms.util.CmsStringUtil;
032import org.opencms.util.CmsUUID;
033
034import java.util.ArrayList;
035import java.util.Collections;
036import java.util.List;
037import java.util.Map;
038
039import org.apache.commons.collections.Transformer;
040
041/**
042 * One container of a container page.<p>
043 *
044 * @since 8.0
045 */
046public class CmsContainerBean {
047
048    /** A lazy initialized map that describes if a certain element if part of this container. */
049    private transient Map<CmsUUID, Boolean> m_containsElement;
050
051    /** Flag indicating this container is used on detail pages only. */
052    private boolean m_detailOnly;
053
054    /** The id's of of all elements in this container. */
055    private transient List<CmsUUID> m_elementIds;
056
057    /** The container elements. */
058    private final List<CmsContainerElementBean> m_elements;
059
060    /**
061     * Indicates whether this container not nested,
062     * or in case of a detail only container page the starting point of a detail only container hierarchy.
063     **/
064    private boolean m_isRootContainer;
065
066    /** The maximal number of elements in the container. */
067    private int m_maxElements;
068
069    /** The container name. */
070    private final String m_name;
071
072    /** The optional container parameter. */
073    private String m_param;
074
075    /** The parent element instance id. */
076    private String m_parentInstanceId;
077
078    /** The container type. */
079    private String m_type;
080
081    /** The container width set by the rendering container tag. */
082    private String m_width;
083
084    /**
085     * Creates a new container bean.<p>
086     *
087     * @param name the container name
088     * @param type the container type
089     * @param parentInstanceId the parent instance id
090     * @param isRootContainer <code>true</code> if this container not nested
091     * @param maxElements the maximal number of elements in the container
092     * @param elements the elements
093     **/
094    public CmsContainerBean(
095        String name,
096        String type,
097        String parentInstanceId,
098        boolean isRootContainer,
099        int maxElements,
100        List<CmsContainerElementBean> elements) {
101
102        m_name = name;
103        m_type = type;
104        m_parentInstanceId = parentInstanceId;
105        m_isRootContainer = isRootContainer;
106        m_maxElements = maxElements;
107        m_elements = (elements == null
108        ? Collections.<CmsContainerElementBean> emptyList()
109        : Collections.unmodifiableList(elements));
110    }
111
112    /**
113     * Creates a new container bean with an unlimited number of elements.<p>
114     *
115     * @param name the container name
116     * @param type the container type
117     * @param parentInstanceId the parent instance id
118     * @param isRootContainer <code>true</code> if this container not nested
119     * @param elements the elements
120     **/
121    public CmsContainerBean(
122        String name,
123        String type,
124        String parentInstanceId,
125        boolean isRootContainer,
126        List<CmsContainerElementBean> elements) {
127
128        this(name, type, parentInstanceId, isRootContainer, -1, elements);
129    }
130
131    /**
132     * Returns <code>true</code> if the element with the provided id is contained in this container.<p>
133     *
134     * @param elementId the element id to check
135     *
136     * @return <code>true</code> if the element with the provided id is contained in this container
137     */
138    public boolean containsElement(CmsUUID elementId) {
139
140        return getElementIds().contains(elementId);
141    }
142
143    /**
144     * Creates a copy of this bean, but with the element list replaced with something else.
145     *
146     * @param elements the new list of elements for the copy
147     * @return the copied container bean
148     */
149    public CmsContainerBean copyWithNewElements(List<CmsContainerElementBean> elements) {
150
151        return new CmsContainerBean(
152            getName(),
153            getType(),
154            getParentInstanceId(),
155            isRootContainer(),
156            getMaxElements(),
157            elements);
158    }
159
160    /**
161     * Returns a lazy initialized map that describes if a certain element if part of this container.<p>
162     *
163     * @return a lazy initialized map that describes if a certain element if part of this container
164     */
165    public Map<CmsUUID, Boolean> getContainsElement() {
166
167        if (m_containsElement == null) {
168            m_containsElement = CmsCollectionsGenericWrapper.createLazyMap(new Transformer() {
169
170                public Object transform(Object input) {
171
172                    return Boolean.valueOf(containsElement((CmsUUID)input));
173                }
174            });
175        }
176        return m_containsElement;
177    }
178
179    /**
180     * Returns the id's of all elements in this container.<p>
181     *
182     * @return the id's of all elements in this container
183     */
184    public List<CmsUUID> getElementIds() {
185
186        if (m_elementIds == null) {
187            m_elementIds = new ArrayList<CmsUUID>(m_elements.size());
188            for (CmsContainerElementBean element : m_elements) {
189                m_elementIds.add(element.getId());
190            }
191        }
192        return m_elementIds;
193    }
194
195    /**
196     * Returns the elements in this container.<p>
197     *
198     * @return the elements in this container
199     */
200    public List<CmsContainerElementBean> getElements() {
201
202        return m_elements;
203    }
204
205    /**
206     * Returns the maximal number of elements in this container.<p>
207     *
208     * @return the maximal number of elements in this container
209     */
210    public int getMaxElements() {
211
212        return m_maxElements;
213    }
214
215    /**
216     * Returns the name of this container.<p>
217     *
218     * @return the name of this container
219     */
220    public String getName() {
221
222        return m_name;
223    }
224
225    /**
226     * Returns the (optional) container parameter.<p>
227     *
228     * This is useful for a dynamically generated nested container,
229     * to pass information to the formatter used inside that container.
230     *
231     * If no parameters have been set, this will return <code>null</code>
232     *
233     * @return the (optional) container parameter
234     */
235    public String getParam() {
236
237        return m_param;
238    }
239
240    /**
241     * Returns the the parent instance id.<p>
242     *
243     * @return the parent instance id
244     */
245    public String getParentInstanceId() {
246
247        return m_parentInstanceId;
248    }
249
250    /**
251     * Returns the type of this container.<p>
252     *
253     * @return the type of this container
254     */
255    public String getType() {
256
257        return m_type;
258    }
259
260    /**
261     * Returns the container width set by the rendering container tag.<p>
262     *
263     * @return the container width
264     */
265    public String getWidth() {
266
267        return m_width;
268    }
269
270    /**
271     * Returns if this container is used on detail pages only.<p>
272     *
273     * @return <code>true</code> if this container is used on detail pages only
274     */
275    public boolean isDetailOnly() {
276
277        return m_detailOnly;
278    }
279
280    /**
281     * Returns if the given container is a nested container.<p>
282     *
283     * @return <code>true</code> if the given container is a nested container
284     */
285    public boolean isNestedContainer() {
286
287        return CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_parentInstanceId);
288    }
289
290    /**
291     * Returns if this container not nested,
292     * or in case of a detail only container page the starting point of a detail only container hierarchy.<p>
293     *
294     * @return <code>true</code> if this container not nested
295     */
296    public boolean isRootContainer() {
297
298        return m_isRootContainer;
299    }
300
301    /**
302     * Sets if this container is used on detail pages only.<p>
303     *
304     * @param detailOnly <code>true</code> if this container is used on detail pages only
305     */
306    public void setDetailOnly(boolean detailOnly) {
307
308        m_detailOnly = detailOnly;
309    }
310
311    /**
312     * Sets the maximal number of elements in the container.<p>
313     *
314     * @param maxElements the maximal number of elements to set
315     */
316    public void setMaxElements(int maxElements) {
317
318        m_maxElements = maxElements;
319    }
320
321    /**
322     * Sets the container parameter.<p>
323     *
324     * This is useful for a dynamically generated nested container,
325     * to pass information to the formatter used inside that container.
326     *
327     * @param param the parameter String to set
328     */
329    public void setParam(String param) {
330
331        m_param = param;
332    }
333
334    /**
335     * Sets the container type.<p>
336     *
337     * @param type the container type
338     */
339    public void setType(String type) {
340
341        m_type = type;
342    }
343
344    /**
345     * Sets the client side render with of this container.<p>
346     *
347     * @param width the client side render with of this container
348     */
349    public void setWidth(String width) {
350
351        m_width = width;
352    }
353}