001: package org.apache.turbine.services.xmlrpc.util;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.io.BufferedReader;
023: import java.io.File;
024: import java.io.FileInputStream;
025: import java.io.FileWriter;
026: import java.io.IOException;
027: import java.io.InputStreamReader;
028: import java.io.StringWriter;
029:
030: import javax.mail.internet.MimeUtility;
031:
032: import org.apache.commons.lang.StringUtils;
033:
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036:
037: import org.apache.turbine.Turbine;
038:
039: import org.apache.turbine.services.servlet.TurbineServlet;
040:
041: /**
042: * A Handler for use with the XML-RPC service that will deal
043: * with clients sending file to the server (Turbine application)
044: * and clients getting files from the server (Turbine application).
045: *
046: * 1) In the first case where the client sends a file to the server,
047: * the client has encoded the file contents and passes those
048: * encoded file contents on to the server:
049: *
050: * Client --------> encoded file contents -------------> Server
051: *
052: * The server must then decode the file contents and write the
053: * decoded file contents to disk.
054: *
055: * 2) In the second case where the client gets a file from the
056: * the server, the server has encoded the file contents and
057: * passes those encoded file contents on to the client:
058: *
059: * Client <------- encoded file contents <------------- Server
060: *
061: * The client must then decode the file contents and write the
062: * decoded file contents to disk.
063: *
064: * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
065: * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
066: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
067: * @version $Id: FileHandler.java 534527 2007-05-02 16:10:59Z tv $
068: * @deprecated This is not scope of the Service itself but of an
069: * application which uses the service. This class shouldn't
070: * be part of Turbine but of an addon application.
071: */
072: public class FileHandler {
073: /** Logging */
074: private static Log log = LogFactory.getLog(FileHandler.class);
075:
076: /**
077: * Default Constructor
078: */
079: public FileHandler() {
080: }
081:
082: /**
083: * The client has indicated that it would like
084: * to send a file to the server and have it
085: * stored in a certain location on the server.
086: *
087: * So a client Turbine application might use the
088: * following bit of code to send a file to a server
089: * Turbine application:
090: *
091: * TurbineXmlRpc.executeRpc("file.send", params)
092: *
093: * Where:
094: *
095: * params.get(0) = contents of the file as a string.
096: * params.get(1) = the name the file should have when it lands.
097: * params.get(2) = property describing where the file should land.
098: *
099: * @param fileContents The contents of the file to store. It
100: * is assumed that any xml content is properly encoded!
101: *
102: * @param fileName Name to give the file created to store
103: * the contents.
104: *
105: * @param targetLocationProperty storage location of this file
106: * is controlled by this property that is specified in
107: * the TR.props file or an included properties file.
108: */
109: public boolean send(String fileContents,
110: String targetLocationProperty, String fileName) {
111: /*
112: * Simply take the file contents that have been sent
113: * by the client and write them to disk in the
114: * specified location: targetLocationProperty specifies
115: * the directory in which to place the fileContents
116: * with the name fileName.
117: */
118: return writeFileContents(fileContents, targetLocationProperty,
119: fileName);
120: }
121:
122: /**
123: * The client has indicated that it would like
124: * to get a file from the server.
125: *
126: * So a client Turbine application might use the
127: * following bit of code to get a file from a server
128: * Turbine application:
129: *
130: * TurbineXmlRpc.executeRpc("file.get", params)
131: *
132: * Where:
133: *
134: * params.get(0) = the name the file should have when it lands.
135: * params.get(1) = property describing where the file should land.
136: *
137: * @param fileName Name to give the file created to store
138: * the contents.
139: *
140: * @param targetLocationProperty storage location of this file
141: * is controlled by this property that is specified in
142: * the TR.props file or an included properties file.
143: *
144: * @return the file contents encoded with base64.
145: */
146: public String get(String targetLocationProperty, String fileName) {
147: /*
148: * Place the contents of the file with the name
149: * fileName in the directory specified by
150: * targetLocationProperty.
151: */
152: return readFileContents(targetLocationProperty, fileName);
153: }
154:
155: /**
156: * Return the content of file encoded for transfer
157: *
158: * @param targetLocationProperty path to file to encode.
159: * @param fileName file to encode
160: * @return String encoded contents of the requested file.
161: */
162: public static String readFileContents(
163: String targetLocationProperty, String fileName) {
164: String location = Turbine.getConfiguration().getString(
165: targetLocationProperty);
166:
167: if (StringUtils.isEmpty(location)) {
168: log.error("Could not load Property for location "
169: + targetLocationProperty);
170: return null;
171: }
172:
173: File tmpF = new File(".");
174:
175: StringBuffer sb = new StringBuffer();
176: sb.append(location);
177: sb.append(File.separator);
178: sb.append(fileName);
179:
180: String file = TurbineServlet.getRealPath(sb.toString());
181:
182: StringWriter sw = null;
183: BufferedReader reader = null;
184: try {
185: /*
186: * This little routine was borrowed from the
187: * velocity ContentResource class.
188: */
189:
190: sw = new StringWriter();
191:
192: reader = new BufferedReader(new InputStreamReader(
193: new FileInputStream(file)));
194:
195: char buf[] = new char[1024];
196: int len = 0;
197:
198: while ((len = reader.read(buf, 0, 1024)) != -1) {
199: sw.write(buf, 0, len);
200: }
201:
202: return MimeUtility.encodeText(sw.toString(), "UTF-8", "B");
203: } catch (IOException ioe) {
204: log.error("[FileHandler] Unable to encode the contents "
205: + "of the request file.", ioe);
206:
207: return null;
208: } finally {
209: try {
210: if (sw != null) {
211: sw.close();
212: }
213: if (reader != null) {
214: reader.close();
215: }
216: } catch (Exception e) {
217: }
218: }
219: }
220:
221: public static boolean writeFileContents(String fileContents,
222: String targetLocationProperty, String fileName) {
223: String location = Turbine.getConfiguration().getString(
224: targetLocationProperty);
225:
226: if (StringUtils.isEmpty(location)) {
227: log.error("Could not load Property for location "
228: + targetLocationProperty);
229: return false;
230: }
231:
232: /*
233: * The target location is always within the webapp to
234: * make the application fully portable. So use the TurbineServlet
235: * service to map the target location in the webapp space.
236: */
237:
238: File targetLocation = new File(TurbineServlet
239: .getRealPath(location));
240:
241: if (!targetLocation.exists()) {
242: /*
243: * If the target location doesn't exist then
244: * attempt to create the target location and any
245: * necessary parent directories as well.
246: */
247: if (!targetLocation.mkdirs()) {
248: log
249: .error("[FileHandler] Could not create target location: "
250: + targetLocation
251: + ". Cannot transfer file from client.");
252:
253: return false;
254: } else {
255: log
256: .info("[FileHandler] Creating target location:"
257: + targetLocation
258: + " in order to complete file transfer from client.");
259: }
260: }
261:
262: FileWriter fileWriter = null;
263: try {
264: /*
265: * Try to create the target file and write it out
266: * to the target location.
267: */
268: fileWriter = new FileWriter(targetLocation + "/" + fileName);
269:
270: /*
271: * It is assumed that the file has been encoded
272: * and therefore must be decoded before the
273: * contents of the file are stored to disk.
274: */
275: fileWriter.write(MimeUtility.decodeText(fileContents));
276:
277: return true;
278: } catch (IOException ioe) {
279: log
280: .error(
281: "[FileHandler] Could not write the decoded file "
282: + "contents to disk for the following reason.",
283: ioe);
284:
285: return false;
286: } finally {
287: try {
288: if (fileWriter != null) {
289: fileWriter.close();
290: }
291: } catch (Exception e) {
292: }
293: }
294: }
295:
296: /**
297: * Method to allow a client to remove a file from
298: * the server
299: *
300: * @param sourceLocationProperty
301: * @param sourceFileName
302: */
303: public static void remove(String sourceLocationProperty,
304: String sourceFileName) {
305: String location = Turbine.getConfiguration().getString(
306: sourceLocationProperty);
307:
308: if (StringUtils.isEmpty(location)) {
309: log.error("Could not load Property for location "
310: + sourceLocationProperty);
311: return;
312: }
313:
314: /*
315: * The target location is always within the webapp to
316: * make the application fully portable. So use the TurbineServlet
317: * service to map the target location in the webapp space.
318: */
319: File sourceFile = new File(TurbineServlet
320: .getRealPath(sourceLocationProperty + "/"
321: + sourceFileName));
322:
323: if (sourceFile.exists()) {
324: sourceFile.delete();
325: }
326: }
327: }
|