KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > xml > page > CmsXmlPageFactory


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/xml/page/CmsXmlPageFactory.java,v $
3  * Date : $Date: 2006/03/27 14:53:06 $
4  * Version: $Revision: 1.16 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.xml.page;
33
34 import org.opencms.file.CmsFile;
35 import org.opencms.file.CmsObject;
36 import org.opencms.file.CmsPropertyDefinition;
37 import org.opencms.file.CmsResource;
38 import org.opencms.file.CmsResourceFilter;
39 import org.opencms.file.types.CmsResourceTypeXmlPage;
40 import org.opencms.i18n.CmsEncoder;
41 import org.opencms.loader.CmsXmlContentLoader;
42 import org.opencms.main.CmsException;
43 import org.opencms.main.CmsLog;
44 import org.opencms.main.OpenCms;
45 import org.opencms.xml.CmsXmlEntityResolver;
46 import org.opencms.xml.CmsXmlException;
47 import org.opencms.xml.CmsXmlUtils;
48 import org.opencms.xml.I_CmsXmlDocument;
49 import org.opencms.xml.content.CmsXmlContentFactory;
50 import org.opencms.xml.types.I_CmsXmlSchemaType;
51
52 import java.io.UnsupportedEncodingException JavaDoc;
53 import java.util.Locale JavaDoc;
54
55 import javax.servlet.ServletRequest JavaDoc;
56
57 import org.apache.commons.logging.Log;
58
59 import org.dom4j.Document;
60 import org.dom4j.DocumentHelper;
61 import org.dom4j.Element;
62 import org.xml.sax.EntityResolver JavaDoc;
63
64 /**
65  * Provides factory methods to unmarshal (read) an XML page object.<p>
66  *
67  * @author Alexander Kandzior
68  *
69  * @version $Revision: 1.16 $
70  *
71  * @since 6.0.0
72  */

73 public final class CmsXmlPageFactory {
74
75     /** The log object for this class. */
76     private static final Log LOG = CmsLog.getLog(CmsXmlPageFactory.class);
77
78     /**
79      * No instances of this class should be created.<p>
80      */

81     private CmsXmlPageFactory() {
82
83         // noop
84
}
85
86     /**
87      * Creates a valid XML page document,
88      * containing one empty element in the given locale.<p>
89      *
90      * @param locale the locale to create the XML page for
91      *
92      * @return a valid XML page document
93      */

94     public static Document createDocument(Locale JavaDoc locale) {
95
96         Document doc = DocumentHelper.createDocument();
97         Element pages = doc.addElement(CmsXmlPage.NODE_PAGES);
98         pages.add(I_CmsXmlSchemaType.XSI_NAMESPACE);
99         pages.addAttribute(
100             I_CmsXmlSchemaType.XSI_NAMESPACE_ATTRIBUTE_NO_SCHEMA_LOCATION,
101             CmsXmlPage.XMLPAGE_XSD_SYSTEM_ID);
102
103         Element page = pages.addElement(CmsXmlPage.NODE_PAGE);
104         page.addAttribute(CmsXmlPage.ATTRIBUTE_LANGUAGE, locale.toString());
105
106         return doc;
107     }
108
109     /**
110      * Creates a valid XML page String representation,
111      * containing one empty element in the given locale.<p>
112      *
113      * @param locale the locale to create the XML page for
114      * @param encoding the encoding to use when creating the String from the XML
115      *
116      * @return a valid XML page document as a String
117      */

118     public static String JavaDoc createDocument(Locale JavaDoc locale, String JavaDoc encoding) {
119
120         try {
121             return CmsXmlUtils.marshal(createDocument(locale), encoding);
122         } catch (CmsXmlException e) {
123             // this should never happen
124
LOG.error(Messages.get().getBundle().key(Messages.ERR_XML_PAGE_FACT_CREATE_DOC_0), e);
125             return null;
126         }
127     }
128
129     /**
130      * Factory method to unmarshal (read) a XML page instance from a byte array
131      * that contains XML data.<p>
132      *
133      * When unmarshalling, the encoding is read directly from the XML header.
134      * The given encoding is used only when marshalling the XML again later.<p>
135      *
136      * @param xmlData the XML data in a byte array
137      * @param encoding the encoding to use when marshalling the XML page later
138      * @param resolver the XML entitiy resolver to use
139      * @return a XML page instance unmarshalled from the byte array
140      * @throws CmsXmlException if something goes wrong
141      */

142     public static CmsXmlPage unmarshal(byte[] xmlData, String JavaDoc encoding, EntityResolver resolver) throws CmsXmlException {
143
144         return new CmsXmlPage(CmsXmlUtils.unmarshalHelper(xmlData, resolver), encoding);
145     }
146
147     /**
148      * Factory method to unmarshal (read) a XML page instance from a OpenCms VFS file
149      * that contains XML data.<p>
150      *
151      * @param cms the current cms object
152      * @param file the file with the XML data to unmarshal
153      * @return a XML page instance unmarshalled from the provided file
154      * @throws CmsXmlException if something goes wrong
155      */

156     public static CmsXmlPage unmarshal(CmsObject cms, CmsFile file) throws CmsXmlException {
157
158         return CmsXmlPageFactory.unmarshal(cms, file, true);
159     }
160
161     /**
162      * Factory method to unmarshal (read) a XML page instance from a OpenCms VFS file
163      * that contains XML data, using wither the encoding set
164      * in the XML file header, or the encoding set in the VFS file property.<p>
165      *
166      * If you are not sure about the implications of the encoding issues,
167      * use {@link #unmarshal(CmsObject, CmsFile)} instead.<p>
168      *
169      * @param cms the current cms object
170      * @param file the file with the XML data to unmarshal
171      * @param keepEncoding if true, the encoding spefified in the XML header is used,
172      * otherwise the encoding from the VFS file property is used
173      * @return a XML page instance unmarshalled from the provided file
174      * @throws CmsXmlException if something goes wrong
175      */

176     public static CmsXmlPage unmarshal(CmsObject cms, CmsFile file, boolean keepEncoding) throws CmsXmlException {
177
178         byte[] content = file.getContents();
179
180         String JavaDoc fileName = cms.getSitePath(file);
181         boolean allowRelative = false;
182         try {
183             allowRelative = Boolean.valueOf(
184                 cms.readPropertyObject(fileName, CmsXmlPage.PROPERTY_ALLOW_RELATIVE, false).getValue()).booleanValue();
185         } catch (CmsException e) {
186             // allowRelative will be false
187
}
188
189         String JavaDoc encoding = null;
190         try {
191             encoding = cms.readPropertyObject(fileName, CmsPropertyDefinition.PROPERTY_CONTENT_ENCODING, true).getValue();
192         } catch (CmsException e) {
193             // encoding will be null
194
}
195         if (encoding == null) {
196             encoding = OpenCms.getSystemInfo().getDefaultEncoding();
197         } else {
198             encoding = CmsEncoder.lookupEncoding(encoding, null);
199             if (encoding == null) {
200                 throw new CmsXmlException(Messages.get().container(Messages.ERR_XML_PAGE_FACT_INVALID_ENC_1, fileName));
201             }
202         }
203
204         CmsXmlPage newPage;
205         if (content.length > 0) {
206             // content is initialized
207
if (keepEncoding) {
208                 // use the encoding from the content
209
newPage = unmarshal(content, encoding, new CmsXmlEntityResolver(cms));
210             } else {
211                 // use the encoding from the file property
212
// this usually only triggered by a save operation
213
try {
214                     String JavaDoc contentStr = new String JavaDoc(content, encoding);
215                     newPage = unmarshal(contentStr, encoding, new CmsXmlEntityResolver(cms));
216                 } catch (UnsupportedEncodingException JavaDoc e) {
217                     // this will not happen since the encodig has already been validated
218
throw new CmsXmlException(Messages.get().container(
219                         Messages.ERR_XML_PAGE_FACT_INVALID_ENC_1,
220                         fileName), e);
221                 }
222             }
223         } else {
224             // content is empty
225
newPage = new CmsXmlPage(cms.getRequestContext().getLocale(), encoding);
226         }
227
228         newPage.setFile(file);
229         newPage.setAllowRelativeLinks(allowRelative);
230
231         return newPage;
232     }
233
234     /**
235      * Factory method to unmarshal (read) a XML page instance from
236      * a resource, using the request attributes as cache.<p>
237      *
238      * @param cms the current OpenCms context object
239      * @param resource the resource to unmarshal
240      * @param req the current request
241      *
242      * @return the unmarshaled xmlpage, or null if the given resource was not of type {@link CmsResourceTypeXmlPage}
243      *
244      * @throws CmsException in something goes wrong
245      */

246     public static CmsXmlPage unmarshal(CmsObject cms, CmsResource resource, ServletRequest JavaDoc req) throws CmsException {
247
248         String JavaDoc rootPath = resource.getRootPath();
249
250         if (resource.getTypeId() != CmsResourceTypeXmlPage.getStaticTypeId()) {
251             // sanity check: resource must be of type XML page
252
throw new CmsXmlException(Messages.get().container(
253                 Messages.ERR_XML_PAGE_FACT_NO_XMLPAGE_TYPE_1,
254                 cms.getSitePath(resource)));
255         }
256
257         // try to get the requested page form the current request attributes
258
CmsXmlPage page = (CmsXmlPage)req.getAttribute(rootPath);
259
260         if (page == null) {
261             // unmarshal XML structure from the file content
262
page = unmarshal(cms, CmsFile.upgrade(resource, cms));
263             // store the page that was read as request attribute for future read requests
264
req.setAttribute(rootPath, page);
265         }
266
267         return page;
268     }
269
270     /**
271      * Factory method to unmarshal (read) a XML document instance from
272      * a filename in the VFS, using the request attributes as cache.<p>
273      *
274      * @param cms the current OpenCms context object
275      * @param filename the filename of the resource to unmarshal
276      * @param req the current request
277      *
278      * @return the unmarshaled xml document, or null if the given resource was not of type {@link I_CmsXmlDocument}
279      *
280      * @throws CmsException in something goes wrong
281      */

282     public static I_CmsXmlDocument unmarshal(CmsObject cms, String JavaDoc filename, ServletRequest JavaDoc req) throws CmsException {
283
284         // add site root to filename
285
String JavaDoc rootPath = cms.getRequestContext().addSiteRoot(filename);
286
287         // try to get the requested page form the current request attributes
288
I_CmsXmlDocument doc = (I_CmsXmlDocument)req.getAttribute(rootPath);
289
290         if (doc != null) {
291             return doc;
292         }
293
294         // always use "ignore expiration" filter, date validity must be checked before calling this if required
295
CmsFile file = cms.readFile(filename, CmsResourceFilter.IGNORE_EXPIRATION);
296
297         if (file.getTypeId() == CmsResourceTypeXmlPage.getStaticTypeId()) {
298             // file is of type XML page
299
doc = CmsXmlPageFactory.unmarshal(cms, file);
300         } else if ((OpenCms.getResourceManager().getLoader(file) instanceof CmsXmlContentLoader)) {
301             // file is of type XML content
302
doc = CmsXmlContentFactory.unmarshal(cms, file);
303         } else {
304             // sanity check: file type not an A_CmsXmlDocument
305
throw new CmsXmlException(Messages.get().container(Messages.ERR_XML_PAGE_FACT_NO_XML_DOCUMENT_1, file));
306         }
307
308         // store the page that was read as request attribute for future read requests
309
req.setAttribute(rootPath, doc);
310
311         return doc;
312     }
313
314     /**
315      * Factory method to unmarshal (read) a XML page instance from a String
316      * that contains XML data.<p>
317      *
318      * When unmarshalling, the encoding is read directly from the XML header.
319      * The given encoding is used only when marshalling the XML again later.<p>
320      *
321      * @param xmlData the XML data in a String
322      * @param encoding the encoding to use when marshalling the XML page later
323      * @param resolver the XML entitiy resolver to use
324      * @return a XML page instance unmarshalled from the String
325      * @throws CmsXmlException if something goes wrong
326      */

327     public static CmsXmlPage unmarshal(String JavaDoc xmlData, String JavaDoc encoding, EntityResolver resolver) throws CmsXmlException {
328
329         return new CmsXmlPage(CmsXmlUtils.unmarshalHelper(xmlData, resolver), encoding);
330     }
331 }
Popular Tags