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.ugc;
029
030import org.opencms.file.CmsFile;
031import org.opencms.file.CmsGroup;
032import org.opencms.file.CmsObject;
033import org.opencms.file.CmsResource;
034import org.opencms.file.CmsUser;
035import org.opencms.i18n.CmsLocaleManager;
036import org.opencms.main.CmsException;
037import org.opencms.main.OpenCms;
038import org.opencms.util.CmsStringUtil;
039import org.opencms.util.CmsUUID;
040import org.opencms.xml.content.CmsXmlContent;
041import org.opencms.xml.content.CmsXmlContentFactory;
042import org.opencms.xml.types.I_CmsXmlContentValue;
043
044import java.util.List;
045import java.util.Locale;
046
047import com.google.common.base.Optional;
048
049/**
050 * Parser for form configuration files.<p>
051 */
052public class CmsUgcConfigurationReader {
053
054    /** XML content value name. */
055    public static final String N_CONTENT_TYPE = "ContentType";
056
057    /** XML content value name. */
058    public static final String N_CONTENT_PATH = "ContentPath";
059
060    /** XML content value name. */
061    public static final String N_NAME_PATTERN = "NamePattern";
062
063    /** XML content value name. */
064    public static final String N_LOCALE = "Locale";
065
066    /** XML content value name. */
067    public static final String N_UPLOAD_PATH = "UploadPath";
068
069    /** XML content value name. */
070    public static final String N_MAX_UPLOAD_SIZE = "MaxUploadSize";
071
072    /** XML content value name. */
073    public static final String N_MAX_NUM_CONTENTS = "MaxNumContents";
074
075    /** XML content value name. */
076    public static final String N_QUEUE_WAIT_TIME = "QueueWaitTime";
077
078    /** XML content value name. */
079    public static final String N_QUEUE_MAX_LENGTH = "QueueMaxLength";
080
081    /** XML content value name. */
082    public static final String N_AUTO_PUBLISH = "AutoPublish";
083
084    /** XML content value name. */
085    public static final String N_VALID_EXTENSIONS = "ValidExtensions";
086
087    /** XML content value name. */
088    public static final String N_USER_FOR_GUEST = "UserForGuest";
089
090    /** XML content value name. */
091    public static final String N_PROJECT_GROUP = "ProjectGroup";
092
093    /** The CMS context used by this configuration reader. */
094    private CmsObject m_cms;
095
096    /** The XML content from which the configuration is read. */
097    private CmsXmlContent m_content;
098
099    /** The separator used for separating the configured valid file name extensions for uploaded files. */
100    public static final String EXTENSIONS_SEPARATOR = ";";
101
102    /**
103     * Creates a new instance.<p>
104     *
105     * @param cms the CMS context to use
106     */
107    public CmsUgcConfigurationReader(CmsObject cms) {
108
109        m_cms = cms;
110    }
111
112    /**
113     * Reads the given configuration file.<p>
114     *
115     * @param configFile the configuration file to read
116     * @return the configuration data read from the file
117     *
118     * @throws CmsException if something goes wrong
119     */
120    public CmsUgcConfiguration readConfiguration(CmsFile configFile) throws CmsException {
121
122        m_content = CmsXmlContentFactory.unmarshal(m_cms, configFile);
123        String resourceType = getStringValue(N_CONTENT_TYPE);
124        String contentPath = getStringValue(N_CONTENT_PATH);
125        CmsResource contentPathResource = m_cms.readResource(contentPath);
126        String namePattern = getStringValue(N_NAME_PATTERN);
127        String localeStr = getStringValue(N_LOCALE);
128        OpenCms.getLocaleManager();
129        Locale locale = CmsLocaleManager.getLocale(localeStr);
130        Optional<CmsResource> uploadPathResource = Optional.absent();
131        String uploadPath = getStringValue(N_UPLOAD_PATH);
132        if (uploadPath != null) {
133            uploadPathResource = Optional.of(m_cms.readResource(uploadPath));
134        }
135        Optional<Long> maxUploadSize = getLongValue(N_MAX_UPLOAD_SIZE);
136        Optional<Integer> maxNumContents = getIntValue(N_MAX_NUM_CONTENTS);
137        Optional<Long> queueWaitTime = getLongValue(N_QUEUE_WAIT_TIME);
138        Optional<Integer> maxQueueLength = getIntValue(N_QUEUE_MAX_LENGTH);
139        boolean autoPublish = Boolean.parseBoolean(getStringValue(N_AUTO_PUBLISH));
140        String validExtensionsStr = getStringValue(N_VALID_EXTENSIONS);
141        Optional<List<String>> validExtensions = Optional.absent();
142        if (validExtensionsStr != null) {
143            validExtensionsStr = validExtensionsStr.trim();
144            List<String> extensions = CmsStringUtil.splitAsList(validExtensionsStr, EXTENSIONS_SEPARATOR);
145            validExtensions = Optional.of(extensions);
146        }
147
148        String userForGuestStr = getStringValue(N_USER_FOR_GUEST);
149        Optional<CmsUser> userForGuest = Optional.absent();
150        if (userForGuestStr != null) {
151            userForGuest = Optional.of(m_cms.readUser(userForGuestStr.trim()));
152        }
153
154        String projectGroupStr = getStringValue(N_PROJECT_GROUP);
155        CmsGroup projectGroup = m_cms.readGroup(projectGroupStr.trim());
156        CmsUUID id = configFile.getStructureId();
157        CmsUgcConfiguration result = new CmsUgcConfiguration(
158            id,
159            userForGuest,
160            projectGroup,
161            resourceType,
162            contentPathResource,
163            namePattern,
164            locale,
165            uploadPathResource,
166            maxUploadSize,
167            maxNumContents,
168            queueWaitTime,
169            maxQueueLength,
170            autoPublish,
171            validExtensions);
172        result.setPath(configFile.getRootPath());
173        return result;
174    }
175
176    /**
177     * Parses an optional integer value.<p>
178     *
179     * @param path the xpath of the content field
180     * @return the optional integer value in that field
181     */
182    private Optional<Integer> getIntValue(String path) {
183
184        return longToInt(getLongValue(path));
185    }
186
187    /**
188     * Parses an optional long value.<p>
189     *
190     * @param path the xpath of the content element
191     * @return  the optional long value in that field
192     */
193    private Optional<Long> getLongValue(String path) {
194
195        String stringValue = getStringValue(path);
196        if (stringValue == null) {
197            return Optional.absent();
198        } else {
199            try {
200                return Optional.<Long> of(Long.valueOf(stringValue.trim()));
201            } catch (NumberFormatException e) {
202                throw new NumberFormatException("Could not read a number from " + path + " ,value= " + stringValue);
203            }
204        }
205    }
206
207    /**
208     * Reads the XML content value for a given xpath.<p>
209     *
210     * Returns null if no value was found at that path.<p>
211     *
212     * @param path the XML content xpath
213     *
214     * @return the value for that path as a string
215     */
216    private String getStringValue(String path) {
217
218        I_CmsXmlContentValue value = m_content.getValue(path, Locale.ENGLISH);
219        if (value == null) {
220            return null;
221        } else {
222            return value.getStringValue(m_cms);
223        }
224    }
225
226    /**
227     * Converts an optional long value to an optional integer value.<p>
228     *
229     * @param optLong the optional long value
230     *
231     * @return the optional integer value
232     */
233    private Optional<Integer> longToInt(Optional<Long> optLong) {
234
235        if (optLong.isPresent()) {
236            return Optional.fromNullable((Integer.valueOf((int)optLong.get().longValue())));
237        } else {
238            return Optional.absent();
239        }
240    }
241}