View Javadoc

1   /*
2    * FCKeditor - The text editor for Internet - http://www.fckeditor.net
3    * Copyright (C) 2004-2010 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.StringWriter;
24  import java.util.List;
25  import java.util.Map;
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.connector.Connector;
37  import net.fckeditor.handlers.Command;
38  import net.fckeditor.handlers.ResourceType;
39  import net.fckeditor.localization.LocalizedMessages;
40  import net.fckeditor.requestcycle.ThreadLocalData;
41  import net.fckeditor.tool.Utils;
42  
43  import org.w3c.dom.Document;
44  import org.w3c.dom.Element;
45  
46  /**
47   * Represents the <a href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Server_Side_Integration#The_Commands"
48   * target="_blank">XML response</a> for the File Browser <code>GET</code>
49   * requests.
50   * 
51   * @version $Id: GetResponse.java 4785 2009-12-21 20:10:28Z mosipov $
52   */
53  public class GetResponse {
54  
55  	/** Underlying DOM document */
56  	protected Document document;
57  	/** Error element, in case of an invalid request */
58  	protected Element errorElement;
59  	/** Folders element, in case of a <code>GetResources</code> request */
60  	protected Element foldersElement;
61  	/** Files element, in case of a <code>GetResources</code> request */
62  	protected Element filesElement;
63  
64  	/** Error number OK */
65  	public static final int EN_OK = 0;
66  
67  	/** Error number CUSTOM ERROR */
68  	public static final int EN_CUSTOM_ERROR = 1;
69  
70  	/** Error number FOLDER ALREADY EXISTS */
71  	public static final int EN_FOLDER_ALREADY_EXISTS_ERROR = 101;
72  
73  	/** Error number INVALID NEW FOLDER NAME */
74  	public static final int EN_INVALID_NEW_FOLDER_NAME_ERROR = 102;
75  
76  	/** Error number SECURITY ERROR */
77  	public static final int EN_CREATE_FOLDER_SECURITY_ERROR = 103;
78  
79  	/** Error number UNKNOWN ERROR */
80  	public static final int EN_UKNOWN_CREATE_FOLDER_ERROR = 110;
81  
82  	/**
83  	 * Constructs a response with a specific error number and message.
84  	 * 
85  	 * @param number
86  	 *            the error number of the new get response
87  	 * @param message
88  	 *            the specific message of the new get response
89  	 * @throws RuntimeException
90  	 *             if creation of the underlying DOM document failed
91  	 */
92  	public GetResponse(int number, String message) {
93  		try {
94  			DocumentBuilderFactory factory = DocumentBuilderFactory
95  					.newInstance();
96  			DocumentBuilder builder = factory.newDocumentBuilder();
97  			document = builder.newDocument();
98  		} catch (ParserConfigurationException e) {
99  			throw new RuntimeException(e);
100 		}
101 
102 		Element root = document.createElement("Connector");
103 		document.appendChild(root);
104 		setError(number, message);
105 	}
106 
107 	/**
108 	 * Constructs a successful response for a specific command and resource
109 	 * type.
110 	 * 
111 	 * @param command
112 	 *            the current command of the new get response
113 	 * @param type
114 	 *            the current resource type of the new get response
115 	 * @param currentFolder
116 	 *            the current folder of the new get response
117 	 * @param constructedUrl
118 	 *            the final URL of the new get response
119 	 * @throws RuntimeException
120 	 *             if creation of the underlying DOM document failed
121 	 */
122 	public GetResponse(Command command, ResourceType type,
123 			String currentFolder, String constructedUrl) {
124 
125 		try {
126 			DocumentBuilderFactory factory = DocumentBuilderFactory
127 					.newInstance();
128 			DocumentBuilder builder = factory.newDocumentBuilder();
129 			document = builder.newDocument();
130 		} catch (ParserConfigurationException e) {
131 			throw new RuntimeException(e);
132 		}
133 
134 		Element root = document.createElement("Connector");
135 		document.appendChild(root);
136 		root.setAttribute("command", command.getName());
137 		root.setAttribute("resourceType", type.getName());
138 
139 		Element currentFolderElement = document.createElement("CurrentFolder");
140 		currentFolderElement.setAttribute("path", currentFolder);
141 
142 		currentFolderElement.setAttribute("url", constructedUrl);
143 		root.appendChild(currentFolderElement);
144 
145 	}
146 
147 	/**
148 	 * Constructs a response with a specific error number only.
149 	 * 
150 	 * @param number
151 	 *            the error number of the new get response
152 	 * @throws RuntimeException
153 	 *             if creation of the underlying DOM document failed
154 	 */
155 	public GetResponse(int number) {
156 		this(number, null);
157 	}
158 
159 	/**
160 	 * Sets the error number and specific message of this get response.
161 	 * 
162 	 * @param number
163 	 *            the error number of this get response
164 	 * @param message
165 	 *            the specific message of this get response
166 	 */
167 	public void setError(int number, String message) {
168 
169 		if (errorElement == null) {
170 			errorElement = document.createElement("Error");
171 			document.getDocumentElement().appendChild(errorElement);
172 		}
173 
174 		errorElement.setAttribute("number", String.valueOf(number));
175 		if (Utils.isNotEmpty(message))
176 			errorElement.setAttribute("text", message);
177 
178 	}
179 
180 	/**
181 	 * Sets the error number of this get response.
182 	 * 
183 	 * @param number
184 	 *            the error number of this get response
185 	 */
186 	public void setError(int number) {
187 		setError(number, null);
188 	}
189 
190 	/**
191 	 * Sets the folders of this get response.
192 	 * 
193 	 * @see Connector#getFolders(ResourceType, String)
194 	 * @param folders
195 	 *            the folders of this get response
196 	 */
197 	public void setFolders(final List<String> folders) {
198 		if (foldersElement != null) {
199 			Element parent = (Element) foldersElement.getParentNode();
200 			parent.removeChild(foldersElement);
201 		}
202 
203 		foldersElement = document.createElement("Folders");
204 		document.getDocumentElement().appendChild(foldersElement);
205 
206 		for (String folder : folders) {
207 			Element folderElement = document.createElement("Folder");
208 			folderElement.setAttribute("name", folder);
209 			foldersElement.appendChild(folderElement);
210 		}
211 	}
212 
213 	/**
214 	 * Sets the folders of this get response.
215 	 * 
216 	 * @see Connector#getFiles(ResourceType, String)
217 	 * @param files
218 	 *            the files of this get response
219 	 */
220 	public void setFiles(final List<Map<String, Object>> files) {
221 		if (filesElement != null) {
222 			Element parent = (Element) filesElement.getParentNode();
223 			parent.removeChild(filesElement);
224 		}
225 
226 		filesElement = document.createElement("Files");
227 		document.getDocumentElement().appendChild(filesElement);
228 
229 		long length = 1L;
230 		long tempLength;
231 
232 		for (Map<String, Object> file : files) {
233 			Element fileElement = document.createElement("File");
234 			fileElement.setAttribute("name", (String) file
235 					.get(Connector.KEY_NAME));
236 			tempLength = ((Number) file.get(Connector.KEY_SIZE)).longValue();
237 			if (tempLength > 1024L)
238 				length = tempLength / 1024L;
239 			fileElement.setAttribute("size", String.valueOf(length));
240 			filesElement.appendChild(fileElement);
241 		}
242 	}
243 
244 	/**
245 	 * Creates the XML representation of this get response. The underlying DOM
246 	 * document will transformed to a string.
247 	 * 
248 	 * @throws RuntimeException
249 	 *             if creation failed
250 	 * @return XML representation of this get response
251 	 */
252 	@Override
253 	public String toString() {
254 		document.getDocumentElement().normalize();
255 		TransformerFactory factory = TransformerFactory.newInstance();
256 
257 		StringWriter sw = new StringWriter();
258 
259 		try {
260 			Transformer transformer = factory.newTransformer();
261 
262 			DOMSource source = new DOMSource(document);
263 			StreamResult result = new StreamResult(sw);
264 
265 			transformer.transform(source, result);
266 		} catch (TransformerException e) {
267 			throw new RuntimeException(e);
268 		}
269 
270 		return sw.toString();
271 	}
272 
273 	/** Creates an <code>OK</code> response. */
274 	public static GetResponse getOK() {
275 		return new GetResponse(EN_OK);
276 	}
277 
278 	/** Creates an <code>INVALID COMMAND</code> error. */
279 	public static GetResponse getInvalidCommandError() {
280 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
281 				.getRequest());
282 		return new GetResponse(EN_CUSTOM_ERROR, lm.getInvalidCommandSpecified());
283 	}
284 
285 	/** Creates an <code>INVALID RESOURCE TYPE</code> error. */
286 	public static GetResponse getInvalidResourceTypeError() {
287 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
288 				.getRequest());
289 		return new GetResponse(EN_CUSTOM_ERROR, lm
290 				.getInvalidResouceTypeSpecified());
291 	}
292 
293 	/** Creates an <code>INVALID CURRENT FOLDER</code> error. */
294 	public static GetResponse getInvalidCurrentFolderError() {
295 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
296 				.getRequest());
297 		return new GetResponse(EN_CUSTOM_ERROR, lm
298 				.getInvalidCurrentFolderSpecified());
299 	}
300 
301 	/** Creates a <code>GET RESOURCES DISABLED</code> error. */
302 	public static GetResponse getGetResourcesDisabledError() {
303 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
304 				.getRequest());
305 		return new GetResponse(EN_CUSTOM_ERROR, lm.getGetResourcesDisabled());
306 	}
307 
308 	/** Creates a <code>GET RESOURCES READ</code> error. */
309 	public static GetResponse getGetResourcesReadError() {
310 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
311 				.getRequest());
312 		return new GetResponse(EN_CUSTOM_ERROR, lm.getGetResourcesReadError());
313 	}
314 
315 	/** Creates a <code>CREATE FOLDER DISABLED</code> error. */
316 	public static GetResponse getCreateFolderDisabledError() {
317 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
318 				.getRequest());
319 		return new GetResponse(EN_CUSTOM_ERROR, lm.getCreateFolderDisabled());
320 	}
321 
322 	/** Creates an <code>INVALID NEW FOLDER NAME</code> error. */
323 	public static GetResponse getInvalidNewFolderNameError() {
324 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
325 				.getRequest());
326 		return new GetResponse(EN_INVALID_NEW_FOLDER_NAME_ERROR, lm
327 				.getInvalidNewFolderNameSpecified());
328 	}
329 
330 	/** Creates a <code>FOLDER ALREADY EXISTS</code> error. */
331 	public static GetResponse getFolderAlreadyExistsError() {
332 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
333 				.getRequest());
334 		return new GetResponse(EN_FOLDER_ALREADY_EXISTS_ERROR, lm
335 				.getFolderAlreadyExistsError());
336 	}
337 
338 	/** Creates a <code>CREATE FOLDER WRITE</code> error. */
339 	public static GetResponse getCreateFolderWriteError() {
340 		LocalizedMessages lm = LocalizedMessages.getInstance(ThreadLocalData
341 				.getRequest());
342 		return new GetResponse(EN_UKNOWN_CREATE_FOLDER_ERROR, lm
343 				.getCreateFolderWriteError());
344 	}
345 }