View Javadoc

1   /*
2    * FCKeditor - The text editor for Internet - http://www.fckeditor.net
3    * Copyright (C) 2004-2009 Frederico Caldeira Knabben
4    * 
5    * == BEGIN LICENSE ==
6    * 
7    * Licensed under the terms of any of the following licenses at your
8    * choice:
9    * 
10   *  - GNU General Public License Version 2 or later (the "GPL")
11   *    http://www.gnu.org/licenses/gpl.html
12   * 
13   *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
14   *    http://www.gnu.org/licenses/lgpl.html
15   * 
16   *  - Mozilla Public License Version 1.1 or later (the "MPL")
17   *    http://www.mozilla.org/MPL/MPL-1.1.html
18   * 
19   * == END LICENSE ==
20   */
21  package net.fckeditor.response;
22  
23  import java.io.File;
24  import java.io.FileFilter;
25  import java.io.StringWriter;
26  
27  import javax.xml.parsers.DocumentBuilder;
28  import javax.xml.parsers.DocumentBuilderFactory;
29  import javax.xml.parsers.ParserConfigurationException;
30  import javax.xml.transform.Transformer;
31  import javax.xml.transform.TransformerException;
32  import javax.xml.transform.TransformerFactory;
33  import javax.xml.transform.dom.DOMSource;
34  import javax.xml.transform.stream.StreamResult;
35  
36  import net.fckeditor.handlers.CommandHandler;
37  import net.fckeditor.handlers.ResourceTypeHandler;
38  import net.fckeditor.tool.Utils;
39  
40  import org.apache.commons.io.filefilter.DirectoryFileFilter;
41  import org.apache.commons.io.filefilter.FileFileFilter;
42  import org.w3c.dom.Document;
43  import org.w3c.dom.Element;
44  
45  /**
46   * Creates an XML response for every <code>GET</code> request of the Connector
47   * servlet. This class maps directly to the XML layout descibed <a
48   * href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Server_Side_Integration#The_Commands">here</a>.
49   * 
50   * @version $Id: XmlResponse.java 3840 2009-07-08 20:29:46Z mosipov $
51   * 
52   */
53  public class XmlResponse {
54  
55  	private Document document;
56  	private Element errorElement;
57  	private Element foldersElement;
58  	private Element filesElement;
59  	
60  	/** Error number OK */
61  	public static final int EN_OK = 0;
62  	
63  	/** Error number ERROR */
64  	public static final int EN_ERROR = 1;
65  
66  	/** Error number ALREADY EXISTS */
67  	public static final int EN_ALREADY_EXISTS = 101;
68  
69  	/** Error number INVALID FOLDER NAME */
70  	public static final int EN_INVALID_FOLDER_NAME = 102;
71  
72  	/** Error number SECURITY ERROR */
73  	public static final int EN_SECURITY_ERROR = 103;
74  
75  	/** Error number UNKNOWN ERROR */
76  	public static final int EN_UKNOWN = 110;
77  
78  	/**
79  	 * Use this contructor if want to respond a positive message.
80  	 * 
81  	 * @param command
82  	 * @param resourceType
83  	 * @param currentFolder
84  	 * @param constructedUrl
85  	 */
86  	public XmlResponse(CommandHandler command, ResourceTypeHandler resourceType, 
87  			String currentFolder, String constructedUrl) {
88  
89  		try {
90  			DocumentBuilderFactory factory = DocumentBuilderFactory
91  					.newInstance();
92  			DocumentBuilder builder = factory.newDocumentBuilder();
93  			document = builder.newDocument();
94  		} catch (ParserConfigurationException e) {
95  			throw new RuntimeException(e);
96  		}
97  
98  		Element root = document.createElement("Connector");
99  		document.appendChild(root);
100 		root.setAttribute("command", command.toString());
101 		root.setAttribute("resourceType", resourceType.toString());
102 
103 		Element currentFolderElement = document.createElement("CurrentFolder");
104 		currentFolderElement.setAttribute("path", currentFolder);
105 
106 		currentFolderElement.setAttribute("url", constructedUrl);
107 		root.appendChild(currentFolderElement);
108 
109 	}
110 	
111 	/**
112 	 * 
113 	 * Use this contructor if want to respond a negative/error message with
114 	 * custom text.
115 	 * 
116 	 * @param number
117 	 * @param text
118 	 */
119 	public XmlResponse(int number, String text) {
120 		try {
121 			DocumentBuilderFactory factory = DocumentBuilderFactory
122 					.newInstance();
123 			DocumentBuilder builder = factory.newDocumentBuilder();
124 			document = builder.newDocument();
125 		} catch (ParserConfigurationException e) {
126 			throw new RuntimeException(e);
127 		}
128 
129 		Element root = document.createElement("Connector");
130 		document.appendChild(root);
131 		setError(number, text);
132 	}
133 	
134 	/**
135 	 * Use this contructor if want to respond a negative/error message only.
136 	 * 
137 	 * @param number
138 	 */
139 	public XmlResponse(int number) {
140 		this(number, null);
141 	}
142 
143 	/**
144 	 * Sets an error number with a custom message.
145 	 * 
146 	 * @param number
147 	 * @param text
148 	 */
149 	public void setError(int number, String text) {
150 
151 		if (errorElement == null) {
152 			errorElement = document.createElement("Error");
153 			document.getDocumentElement().appendChild(errorElement);
154 		}
155 
156 		errorElement.setAttribute("number", String.valueOf(number));
157 		if (Utils.isNotEmpty(text))
158 			errorElement.setAttribute("text", text);
159 
160 	}
161 
162 	/**
163 	 * Sets an error number.
164 	 * 
165 	 * @param number
166 	 */
167 	public void setError(int number) {
168 		setError(number, null);
169 	}
170 
171 	/**
172 	 * Lists all folders in the given dir as XML tags.
173 	 * @param dir
174 	 */
175 	public void setFolders(File dir) {
176 
177 		if (foldersElement != null) {
178 			Element parent = (Element) foldersElement.getParentNode();
179 			parent.removeChild(foldersElement);
180 		}
181 
182 		foldersElement = document.createElement("Folders");
183 		document.getDocumentElement().appendChild(foldersElement);
184 
185 		String[] fileList = dir.list(DirectoryFileFilter.DIRECTORY);
186 		for (String file : fileList) {
187 			Element folderElement = document.createElement("Folder");
188 			folderElement.setAttribute("name", file);
189 			foldersElement.appendChild(folderElement);
190 		}
191 	}
192 	
193 	/**
194 	 * Lists all files in the given dir as XML tags.
195 	 * 
196 	 * @param dir
197 	 */
198 	public void setFiles(File dir) {
199 		
200 		if (filesElement != null) {
201 			Element parent = (Element) filesElement.getParentNode();
202 			parent.removeChild(filesElement);
203 		}
204 
205 		filesElement = document.createElement("Files");
206 		document.getDocumentElement().appendChild(filesElement);
207 		
208 		File[] fileList = dir.listFiles((FileFilter) FileFileFilter.FILE);
209 		long length;
210 		for (File file : fileList) {
211 			Element fileElement = document.createElement("File");
212 			fileElement.setAttribute("name", file.getName());
213 			if (file.length() < 1024)
214 				length = 1L;
215 			else 
216 				length = file.length()/1024;
217 			fileElement.setAttribute("size", String.valueOf(length));
218 			filesElement.appendChild(fileElement);
219 		}
220 	}
221 	
222 	/**
223 	 * Lists all folders and files in the given dir as XML tags.
224 	 * 
225 	 * @param dir
226 	 */	
227 	public void setFoldersAndFiles(File dir) {
228 		setFolders(dir);
229 		setFiles(dir);
230 	}
231 	
232 	@Override
233 	public String toString() {
234 		document.getDocumentElement().normalize();
235 		TransformerFactory factory = TransformerFactory.newInstance();
236 
237 		StringWriter sw = new StringWriter();
238 
239 		try {
240 			Transformer transformer = factory.newTransformer();
241 
242 			DOMSource source = new DOMSource(document);
243 			StreamResult result = new StreamResult(sw);
244 
245 			transformer.transform(source, result);
246 		} catch (TransformerException e) {
247 			throw new RuntimeException(e);
248 		}
249 
250 		return sw.toString();
251 	}
252 
253 }