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.ade.containerpage;
029
030import org.opencms.ade.configuration.CmsADEConfigData;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsResource;
033import org.opencms.util.CmsStringUtil;
034import org.opencms.util.CmsUUID;
035import org.opencms.xml.containerpage.CmsContainerBean;
036import org.opencms.xml.containerpage.CmsContainerElementBean;
037import org.opencms.xml.containerpage.CmsContainerPageBean;
038import org.opencms.xml.containerpage.I_CmsFormatterBean;
039
040import java.util.HashMap;
041import java.util.List;
042import java.util.TreeMap;
043
044import com.google.common.collect.Lists;
045import com.google.common.collect.Maps;
046
047/**
048 * This is a simple helper class to more easily produce container page beans to be used as detail-only containers.<p>
049 *
050 *
051 * To use this helper, you will need to set the type or width of each container and then add the resources to be used
052 * as container elements. The type or width must be set because this helper tries to automatically determine a default formatter
053 * for each container element.<p>
054 *
055 * Finally, call the build() method to produce the desired container page bean
056 *
057 * Element settings and nested containers are currently not supported.
058 *
059 */
060public class CmsDetailOnlyContainerPageBuilder {
061
062    /**
063     * Bean containing the information for a single container.<p>
064     */
065    public static class ContainerInfo {
066
067        /** The list of resources to use as container elements. */
068        private List<CmsResource> m_elements = Lists.newArrayList();
069
070        /** The container name. */
071        private String m_name;
072
073        /** Container type. */
074        private String m_type;
075
076        /** Container width. */
077        private String m_width;
078
079        /**
080         * Creates a new instance.<p>
081         *
082         * @param name the container name
083         */
084        public ContainerInfo(String name) {
085
086            m_name = name;
087        }
088
089        /**
090         * Adds a container element resource.<p>
091         *
092         * @param resource the container element resource
093         */
094        public void addResource(CmsResource resource) {
095
096            m_elements.add(resource);
097        }
098
099        /**
100         * Gets the effective container type.<p>
101         *
102         * @return the effective container type
103         */
104        public String getEffectiveType() {
105
106            if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_type)) {
107                return m_name;
108            } else {
109                return m_type;
110            }
111        }
112
113        /**
114         * Gets the effective container width.
115         *
116         * @return the effective container width
117         */
118        public int getEffectiveWidth() {
119
120            try {
121                return Integer.parseInt(m_width);
122            } catch (Exception e) {
123                return -1;
124            }
125        }
126
127        /**
128         * Gets the container name.<p>
129         *
130         * @return the container name
131         */
132        public String getName() {
133
134            return m_name;
135        }
136
137        /**
138         * Gets the container element resources.
139         *
140         * @return the container element resources
141         */
142        public List<CmsResource> getResources() {
143
144            return m_elements;
145        }
146
147        /**
148         * Returns the type.<p>
149         *
150         * @return the type
151         */
152        public String getType() {
153
154            return m_type;
155        }
156
157        /**
158         * Returns the width.<p>
159         *
160         * @return the width
161         */
162        public String getWidth() {
163
164            return m_width;
165        }
166
167        /**
168         * Sets the type.<p>
169         *
170         * @param type the type to set
171         */
172        public void setType(String type) {
173
174            m_type = type;
175        }
176
177        /**
178         * Sets the width.<p>
179         *
180         * @param width the width to set
181         */
182        public void setWidth(String width) {
183
184            m_width = width;
185        }
186    }
187
188    /** The current CMS context. */
189    private CmsObject m_cms;
190
191    /** The sitemap configuration to use for automatically trying to determine the correct formatter. */
192    private CmsADEConfigData m_config;
193
194    /** The map of container info beans, with container names as keys. */
195    private TreeMap<String, ContainerInfo> m_containerInfos = Maps.newTreeMap();
196
197    /**
198     * Creates a new instance.<p>
199     *
200     * @param cms the current CMS context
201     * @param config the sitemap configuration which should be used to determine the
202     */
203    public CmsDetailOnlyContainerPageBuilder(CmsObject cms, CmsADEConfigData config) {
204
205        m_cms = cms;
206        m_config = config;
207    }
208
209    /**
210     * Adds a resource to a container as an element.<p>
211     *
212     * @param name the container name
213     * @param resource the resource to add as a container elementv
214     */
215    public void addContainerElement(String name, CmsResource resource) {
216
217        getContainerInfo(name).getResources().add(resource);
218    }
219
220    /**
221     * Builds the container page bean.<p>
222     *
223     * @return the container page bean
224     */
225    public CmsContainerPageBean build() {
226
227        List<CmsContainerBean> containers = Lists.newArrayList();
228        for (String containerName : m_containerInfos.keySet()) {
229            CmsContainerBean containerBean = buildContainerBean(m_containerInfos.get(containerName));
230            containers.add(containerBean);
231        }
232        return new CmsContainerPageBean(containers);
233    }
234
235    /**
236     * Sets the type of a container.<p>
237     *
238     * @param name the container name
239     * @param type the container type
240     */
241    public void setContainerType(String name, String type) {
242
243        getContainerInfo(name).setType(type);
244    }
245
246    /**
247     * Sets the width of a container.<p>
248     *
249     * @param name the container name
250     * @param width the container width
251     */
252    public void setContainerWidth(String name, String width) {
253
254        getContainerInfo(name).setWidth(width);
255    }
256
257    /**
258     * Builds a container bean.<p>
259     *
260     * @param cnt the object containing the information to store in the container bean
261     * @return the container bean
262     */
263    private CmsContainerBean buildContainerBean(ContainerInfo cnt) {
264
265        List<CmsContainerElementBean> elements = Lists.newArrayList();
266        for (CmsResource resource : cnt.getResources()) {
267            CmsContainerElementBean elementBean = buildContainerElementBean(cnt, resource);
268            elements.add(elementBean);
269        }
270        CmsContainerBean result = new CmsContainerBean(cnt.getName(), cnt.getType(), null, true, elements);
271        return result;
272    }
273
274    /**
275     * Builds the container element bean for a resource.<p>
276     *
277     * @param cnt the container for the element resource
278     * @param resource the resource
279     *
280     * @return the container element bean
281     */
282    private CmsContainerElementBean buildContainerElementBean(ContainerInfo cnt, CmsResource resource) {
283
284        I_CmsFormatterBean formatter = m_config.getFormatters(m_cms, resource).getDefaultFormatter(
285            cnt.getEffectiveType(),
286            cnt.getEffectiveWidth());
287        CmsUUID formatterId = formatter.getJspStructureId();
288        CmsContainerElementBean elementBean = new CmsContainerElementBean(
289            resource.getStructureId(),
290            formatterId,
291            new HashMap<String, String>(),
292            false);
293        return elementBean;
294    }
295
296    /**
297     * Gets the container information for a given container, creating it if it doesn't already exist.<p>
298     *
299     * @param name the container name
300     * @return the container info object
301     */
302    private ContainerInfo getContainerInfo(String name) {
303
304        if (!m_containerInfos.containsKey(name)) {
305            m_containerInfos.put(name, new ContainerInfo(name));
306        }
307        return m_containerInfos.get(name);
308    }
309
310}