KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > importexport > CmsCompatibleCheck


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/importexport/CmsCompatibleCheck.java,v $
3  * Date : $Date: 2006/03/27 14:52:54 $
4  * Version: $Revision: 1.17 $
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.importexport;
33
34 import org.opencms.file.types.CmsResourceTypeFolder;
35 import org.opencms.file.types.CmsResourceTypePlain;
36 import org.opencms.workplace.CmsWorkplace;
37
38 import java.util.List JavaDoc;
39
40 import org.dom4j.Document;
41 import org.dom4j.DocumentHelper;
42 import org.dom4j.Element;
43 import org.dom4j.Node;
44
45 /**
46  * Checks path information on vfs resources.<p>
47  *
48  * @author Alexander Kandzior
49  * @author Thomas Weckert
50  *
51  * @version $Revision: 1.17 $
52  *
53  * @since 6.0.0
54  */

55 public class CmsCompatibleCheck {
56
57     /** Parameter for content body folder. */
58     public static final String JavaDoc VFS_PATH_BODIES = "/system/bodies/";
59     
60     /** Parameter for default module. */
61     public static final String JavaDoc VFS_PATH_DEFAULTMODULE = CmsWorkplace.VFS_PATH_MODULES + "default/";
62     
63     /** Path to content templates folder. */
64     public static final String JavaDoc VFS_PATH_DEFAULT_TEMPLATES = VFS_PATH_DEFAULTMODULE + CmsWorkplace.VFS_DIR_TEMPLATES;
65     
66     /** Default class for templates. */
67     public static final String JavaDoc XML_CONTROL_DEFAULT_CLASS = "com.opencms.template.CmsXmlTemplate";
68
69     /**
70      * Constructor, does nothing.<p>
71      */

72     public CmsCompatibleCheck() {
73
74         // nothing to do here
75
}
76
77     /**
78      * Checks if the resource path information fulfills the rules for template and body paths.<p>
79      *
80      * @param name the absolute path of the resource in the VFS
81      * @param content the content of the resource.
82      * @param type the resource type
83      * @return true if the resource is ok
84      */

85     public boolean isTemplateCompatible(String JavaDoc name, byte[] content, String JavaDoc type) {
86
87         // dont check folders
88
if (CmsResourceTypeFolder.RESOURCE_TYPE_NAME.equals(type)) {
89             return true;
90         }
91         if (name == null) {
92             return false;
93         }
94         if (name.startsWith(CmsCompatibleCheck.VFS_PATH_BODIES)) {
95             // this is a body file
96
if (!CmsResourceTypePlain.getStaticTypeName().equals(type)) {
97                 // only plain files allowed in content/bodys
98
return false;
99             }
100             // to check the rest we have to parse the content
101
try {
102                 Document xmlDoc = DocumentHelper.parseText(new String JavaDoc(content));
103                 for (Node n = (Node)xmlDoc.content().get(0); n != null; n = treeWalker(xmlDoc, n)) {
104                     short ntype = n.getNodeType();
105                     if (((ntype > Node.CDATA_SECTION_NODE) && ntype < Node.DOCUMENT_TYPE_NODE)
106                         || (ntype == Node.ATTRIBUTE_NODE)) {
107                         return false;
108                     }
109                     if (n.getNodeType() == Node.ELEMENT_NODE) {
110                         String JavaDoc tagName = n.getName();
111                         if (!("template".equalsIgnoreCase(tagName) || "xmltemplate".equalsIgnoreCase(tagName))) {
112                             return false;
113                         }
114                     }
115                 }
116             } catch (Exception JavaDoc e) {
117                 return false;
118             }
119
120         } else if (name.startsWith(CmsCompatibleCheck.VFS_PATH_DEFAULT_TEMPLATES)
121             || (name.startsWith(CmsWorkplace.VFS_PATH_MODULES) && name.indexOf("/" + CmsWorkplace.VFS_DIR_TEMPLATES) > -1)) {
122             // this is a template file
123
if (!CmsResourceTypePlain.getStaticTypeName().equals(type)) {
124                 // only plain templates are allowed
125
return false;
126             }
127             // to check the rest we have to parse the content
128
try {
129                 Document xmlDoc = DocumentHelper.parseText(new String JavaDoc(content));
130
131                 // we check the sub nodes from <xmltemplate>
132
// there should be the two elementdefs, one template and some empty text nodes
133
List JavaDoc list = xmlDoc.getRootElement().content();
134                 list = ((Element)list.get(0)).content();
135                 int counterEldefs = 0;
136                 int counterTeplate = 0;
137                 for (int i = 0; i < list.size(); i++) {
138                     Node n = (Node)list.get(i);
139                     short nodeType = n.getNodeType();
140                     if (nodeType == Node.ELEMENT_NODE) {
141                         // allowed is the Elementdef or the template tag
142
String JavaDoc nodeName = n.getName();
143                         if ("elementdef".equalsIgnoreCase(nodeName)) {
144                             // check the rules for the elementdefinitions
145
if (!checkElementDefOk((Element)n)) {
146                                 return false;
147                             }
148                             counterEldefs++;
149                         } else if ("template".equalsIgnoreCase(nodeName)) {
150                             // check if the template node is ok.
151
if (!checkTemplateTagOk((Element)n)) {
152                                 return false;
153                             }
154                             counterTeplate++;
155                         } else {
156                             //this name is not allowed
157
return false;
158                         }
159
160                     } else if (nodeType == Node.TEXT_NODE) {
161                         // text node is only allowed if the value is empty
162
String JavaDoc nodeValue = n.getText();
163                         if ((nodeValue != null) && (nodeValue.trim().length() > 0)) {
164                             return false;
165                         }
166                     } else {
167                         // this nodeType is not allowed
168
return false;
169                     }
170                 }
171                 if (counterEldefs != 2 || counterTeplate != 1) {
172                     // there have to be exactly two elementdefs and one template tag
173
return false;
174                 }
175
176             } catch (Exception JavaDoc e) {
177                 return false;
178             }
179         }
180         return true;
181     }
182
183     /**
184      * Helper for checking the templates from C_VFS_PATH_BODIES.<p>
185      *
186      * @param el the Element to check
187      * @return true if the element definition is ok
188      */

189     private boolean checkElementDefOk(Element el) {
190
191         // first the name
192
String JavaDoc elementName = el.attribute("name").getText();
193         if (!("contenttemplate".equalsIgnoreCase(elementName) || "frametemplate".equalsIgnoreCase(elementName))) {
194             // no other elementdefinition allowed
195
return false;
196         }
197         // now the templateclass only the standard class is allowed
198
String JavaDoc elClass = CmsImport.getChildElementTextValue(el, "CLASS");
199         if (!CmsCompatibleCheck.XML_CONTROL_DEFAULT_CLASS.equals(elClass)) {
200             return false;
201         }
202         String JavaDoc elTemplate = CmsImport.getChildElementTextValue(el, "TEMPLATE");
203         if (elTemplate == null || elTemplate.indexOf(elementName) < 1) {
204             // it must be in the path /content/"elementName"/ or in
205
// the path /system/modules/"modulename"/"elementName"/
206
return false;
207         }
208         return true;
209     }
210
211     /**
212      * Helper for checking the templates from C_VFS_PATH_BODIES.<p>
213      *
214      * @param el the Element to check
215      * @return true if the template is ok
216      */

217     private boolean checkTemplateTagOk(Element el) {
218
219         List JavaDoc list = el.elements();
220         if (list.size() > 3) {
221             // only the one template tag allowed (and the two empty text nodes)
222
return false;
223         }
224         for (int i = 0; i < list.size(); i++) {
225             Node n = (Node)list.get(i);
226             short ntype = n.getNodeType();
227             if (ntype == Node.TEXT_NODE) {
228                 String JavaDoc nodeValue = n.getText();
229                 if ((nodeValue != null) && (nodeValue.trim().length() > 0)) {
230                     return false;
231                 }
232             } else if (ntype == Node.ELEMENT_NODE) {
233                 // this should be <ELEMENT name="frametemplate"/>
234
if (!"element".equalsIgnoreCase(n.getName())) {
235                     return false;
236                 }
237                 if (!"frametemplate".equals(((Element)n).attribute("name").getText())) {
238                     return false;
239                 }
240             } else {
241                 return false;
242             }
243         }
244         return true;
245     }
246
247     /**
248      * Returns the next sibling of a node.<p>
249      *
250      * @param node the node
251      * @return the next sibling, or null
252      */

253     private Node getNextSibling(Node node) {
254
255         Node sibling = null;
256         List JavaDoc content = null;
257         int i = 0;
258
259         Node parent = node.getParent();
260         if (parent != null) {
261             content = ((Element)parent).content();
262             i = content.indexOf(node);
263             if (i < content.size() - 1) {
264                 sibling = (Node)content.get(i + 1);
265             }
266         }
267
268         return sibling;
269     }
270
271     /**
272      * Help method to walk through the DOM document tree.<p>
273      *
274      * @param root the root Node
275      * @param n a Node representing the current position in the tree
276      * @return next node
277      */

278     private Node treeWalker(Node root, Node n) {
279
280         Node nextnode = null;
281         if (n.hasContent()) {
282             // child has child notes itself
283
// process these first in the next loop
284
nextnode = (Node)((Element)n).content().get(0);
285         } else {
286             // child has no subchild.
287
// so we take the next sibling
288
nextnode = treeWalkerBreadth(root, n);
289         }
290         return nextnode;
291     }
292
293     /**
294      * Help method to walk through the document tree by a breadth-first-order.<p>
295      *
296      * @param root the root Node
297      * @param n a Node representing the current position in the tree
298      * @return next node
299      */

300     private Node treeWalkerBreadth(Node root, Node n) {
301
302         if (n == root) {
303             return null;
304         }
305         Node nextnode = null;
306         Node parent = null;
307         nextnode = getNextSibling(n);
308         parent = n.getParent();
309         while (nextnode == null && parent != null && parent != root) {
310             // child has sibling
311
// last chance: we take our parent's sibling
312
// (or our grandparent's sibling...)
313
nextnode = getNextSibling(parent);
314             parent = parent.getParent();
315         }
316         return nextnode;
317     }
318 }
Popular Tags