001/*
002 * File   : $Source$
003 * Date   : $Date$
004 * Version: $Revision$
005 *
006 * This library is part of OpenCms -
007 * the Open Source Content Management System
008 *
009 * Copyright (C) 2002 - 2011 Alkacon Software (http://www.alkacon.com)
010 *
011 * This library is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Lesser General Public
013 * License as published by the Free Software Foundation; either
014 * version 2.1 of the License, or (at your option) any later version.
015 *
016 * This library is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 * Lesser General Public License for more details.
020 *
021 * For further information about Alkacon Software, please see the
022 * company website: http://www.alkacon.com
023 *
024 * For further information about OpenCms, please see the
025 * project website: http://www.opencms.org
026 *
027 * You should have received a copy of the GNU Lesser General Public
028 * License along with this library; if not, write to the Free Software
029 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030 */
031
032package org.opencms.ade.containerpage.inherited;
033
034import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_CONFIGURATION;
035import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_ELEMENT;
036import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_HIDDEN;
037import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_KEY;
038import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_NAME;
039import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_NEWELEMENT;
040import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_ORDERKEY;
041import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_URI;
042import static org.opencms.ade.containerpage.inherited.CmsContainerConfiguration.N_VISIBLE;
043
044import org.opencms.file.CmsFile;
045import org.opencms.file.CmsObject;
046import org.opencms.file.CmsResource;
047import org.opencms.main.CmsException;
048import org.opencms.util.CmsStringUtil;
049import org.opencms.util.CmsUUID;
050import org.opencms.xml.containerpage.CmsContainerElementBean;
051import org.opencms.xml.content.CmsXmlContent;
052import org.opencms.xml.content.CmsXmlContentFactory;
053import org.opencms.xml.content.CmsXmlContentPropertyHelper;
054import org.opencms.xml.content.CmsXmlContentRootLocation;
055import org.opencms.xml.content.I_CmsXmlContentLocation;
056import org.opencms.xml.content.I_CmsXmlContentValueLocation;
057
058import java.util.ArrayList;
059import java.util.HashMap;
060import java.util.List;
061import java.util.Locale;
062import java.util.Map;
063
064/**
065 * A parser class which reads data from inherited container configuration files.<p>
066 */
067public class CmsContainerConfigurationParser {
068
069    /** The internal CMS context used. */
070    private final CmsObject m_cms;
071
072    /** The configuration group which is currently being read. */
073    private Map<String, CmsContainerConfiguration> m_currentConfigurationGroup;
074
075    /** The locale which is currently being read. */
076    private Locale m_currentLocale;
077
078    /** The parse results. */
079    private final Map<Locale, Map<String, CmsContainerConfiguration>> m_results;
080
081    /**
082     * Creates a new configuration parser.<p>
083     *
084     * @param cms the current CMS context
085     */
086    public CmsContainerConfigurationParser(CmsObject cms) {
087
088        m_cms = cms;
089        m_results = new HashMap<Locale, Map<String, CmsContainerConfiguration>>();
090    }
091
092    /**
093     * Gets the parsed results as a map.<p>
094     *
095     * @return the parse results
096     */
097    public Map<Locale, Map<String, CmsContainerConfiguration>> getParsedResults() {
098
099        return m_results;
100    }
101
102    /**
103     * Parses the contents of a file.<p>
104     *
105     * @param file the file to parse
106     *
107     * @throws CmsException if something goes wrong
108     */
109    public void parse(CmsFile file) throws CmsException {
110
111        CmsXmlContent content = CmsXmlContentFactory.unmarshal(m_cms, file);
112        for (Locale locale : content.getLocales()) {
113            m_currentLocale = locale;
114            CmsXmlContentRootLocation rootLocation = new CmsXmlContentRootLocation(content, locale);
115            parseConfigurationGroup(rootLocation);
116        }
117    }
118
119    /**
120     * Parses the contents of a resource.<p>
121     *
122     * @param resource the resource which should be parsed
123     *
124     * @throws CmsException if something goes wrong
125     */
126    public void parse(CmsResource resource) throws CmsException {
127
128        CmsFile file = m_cms.readFile(resource);
129        parse(file);
130    }
131
132    /**
133     * Parses a group of named configurations from a given XML content location.<p>
134     *
135     * @param location the location from which to read the configuration group
136     */
137    protected void parseConfigurationGroup(I_CmsXmlContentLocation location) {
138
139        List<I_CmsXmlContentValueLocation> locations = location.getSubValues(N_CONFIGURATION);
140        m_currentConfigurationGroup = new HashMap<String, CmsContainerConfiguration>();
141        m_results.put(m_currentLocale, m_currentConfigurationGroup);
142        for (I_CmsXmlContentValueLocation configLocation : locations) {
143            parseSingleConfiguration(configLocation);
144        }
145    }
146
147    /**
148     * Parses a single inheritance configuration from an XML content node.<p>
149     *
150     * @param location the node from which to read the single configuration
151     */
152    protected void parseSingleConfiguration(I_CmsXmlContentValueLocation location) {
153
154        I_CmsXmlContentValueLocation nameLoc = location.getSubValue(N_NAME);
155        if (nameLoc == null) {
156            return;
157        }
158        String name = nameLoc.asString(m_cms);
159        if (CmsStringUtil.isEmptyOrWhitespaceOnly(name)) {
160            return;
161        }
162        List<String> ordering = null;
163        List<I_CmsXmlContentValueLocation> orderKeyLocs = location.getSubValues(N_ORDERKEY);
164        if (orderKeyLocs != null) {
165            ordering = new ArrayList<String>();
166            for (I_CmsXmlContentValueLocation orderKeyLoc : orderKeyLocs) {
167                String orderKey = orderKeyLoc.asString(m_cms);
168                if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(orderKey)) {
169                    ordering.add(orderKey.trim());
170                }
171            }
172        }
173        Map<String, Boolean> visibilities = new HashMap<String, Boolean>();
174        List<I_CmsXmlContentValueLocation> visibleLocs = location.getSubValues(N_VISIBLE);
175        for (I_CmsXmlContentValueLocation visibleLoc : visibleLocs) {
176            String visibleStr = visibleLoc.asString(m_cms);
177            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(visibleStr)) {
178                visibilities.put(visibleStr.trim(), Boolean.TRUE);
179            }
180        }
181
182        List<I_CmsXmlContentValueLocation> hiddenLocs = location.getSubValues(N_HIDDEN);
183        for (I_CmsXmlContentValueLocation hiddenLoc : hiddenLocs) {
184            String hiddenStr = hiddenLoc.asString(m_cms);
185            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(hiddenStr)) {
186                visibilities.put(hiddenStr.trim(), Boolean.FALSE);
187            }
188        }
189
190        List<I_CmsXmlContentValueLocation> newElementLocs = location.getSubValues(N_NEWELEMENT);
191        Map<String, CmsContainerElementBean> newElementBeans = new HashMap<String, CmsContainerElementBean>();
192        for (I_CmsXmlContentValueLocation elementLoc : newElementLocs) {
193            I_CmsXmlContentValueLocation keyLoc = elementLoc.getSubValue(N_KEY);
194            String key = keyLoc.asString(m_cms).trim();
195            I_CmsXmlContentValueLocation actualElementLoc = elementLoc.getSubValue(N_ELEMENT);
196            I_CmsXmlContentValueLocation uriLoc = actualElementLoc.getSubValue(N_URI);
197            CmsUUID structureId = uriLoc.asId(m_cms);
198            if (structureId != null) {
199                Map<String, String> settings = CmsXmlContentPropertyHelper.readProperties(m_cms, actualElementLoc);
200                CmsContainerElementBean newElementBean = new CmsContainerElementBean(
201                    structureId,
202                    CmsUUID.getNullUUID(),
203                    settings,
204                    false);
205                newElementBeans.put(key, newElementBean);
206            }
207        }
208        CmsContainerConfiguration config = new CmsContainerConfiguration(ordering, visibilities, newElementBeans);
209        m_currentConfigurationGroup.put(name, config);
210    }
211
212}